Suped

How to troubleshoot Postfix 'too many connections' errors after upgrading?

Michael Ko profile picture
Michael Ko
Co-founder & CEO, Suped
Published 26 Jun 2025
Updated 22 May 2026
10 min read
Summarize with
Postfix upgrade troubleshooting thumbnail with connection limit warning.
The direct fix is to treat the receiver's limit as a hard per-source-IP connection budget, then verify that Postfix is not opening more active and cached SMTP sessions than that budget allows. After an upgrade, the problem usually is not that Postfix suddenly changed the meaning of a concurrency limit. It is more often that connection reuse, transport grouping, service limits, queue pressure, or a packaging change exposed a limit the old setup happened to stay under.
For a bounce like 421 Too many connections, I start by proving four things: which Postfix service opened the connection, which destination Postfix thought it was delivering to, whether connection caching kept idle sessions open, and whether any other host behind the same NAT or source IP shared the same receiver limit.
  1. Do first: confirm the receiver's exact limit and whether it counts active plus idle SMTP sessions.
  2. Do not do: tune smtpd inbound settings and expect outbound delivery concurrency to change.

Why the upgrade exposed the error

A Postfix upgrade from 3.1 to 3.5 can coincide with changes outside the core SMTP client logic: new OS defaults, changed service files, restored package versions of master.cf, transport maps rebuilt differently, DNS behavior changes, or queue volume that was lower during the old baseline. So I would not assume that Postfix 3.5 changed connection limits until the logs prove it.
The receiver does not care that Postfix has a neat per-transport limit. The receiver sees TCP sessions from your public IP. If that receiver says the limit is 3, then 2 active deliveries, 1 cached idle connection, and 1 connection from another route can already be too many. This is why connection reuse deserves close attention after an upgrade, especially when the receiver complains at the same moment Postfix believes it has obeyed its own limits.
Flowchart for diagnosing Postfix too many connections errors.
Flowchart for diagnosing Postfix too many connections errors.
The setting smtpd_junk_command_limit is for inbound SMTP server behavior. It does not control outbound SMTP client concurrency, so it will not solve a remote provider deferring your outbound mail for too many connections.
  1. Inbound: smtpd settings apply when other systems connect to your Postfix server.
  2. Outbound: smtp transport settings and master.cf service caps apply when your server sends mail out.

Start with the exact evidence

Before changing limits, capture the full deferral line and the active Postfix settings at the time of the event. The important fields are the remote host, status code, Postfix transport name, queue ID, source IP, and timestamp. The receiver's response often tells you whether it wants fewer connections, slower connection attempts, or lower message rate.
Typical receiver deferraltext
421 mwinf5c42 ME Trop de connexions, veuillez verifier votre configuration. Too many connections, slow down. OFR004_104 [104]
Then compare Postfix's view with the network's view. Postfix can show one concurrency number while the receiver sees a higher total because it counts cached sessions, retry bursts, or separate transport services as one shared source-IP pool.
Commands to capture the real statebash
postconf -n | egrep 'smtp_|orange_|wanadoo_' postconf -M | egrep 'orange|wanadoo|smtp' postqueue -p ss -tanp | egrep ':25|:587' journalctl -u postfix --since '30 minutes ago'
If you run several MTAs behind one public address, run the socket count on every sender. Receiver limits are usually per connecting IP, not per hostname, route, or mail stream. That distinction matters when a NAT gateway hides several systems behind one address.
Terminal screenshot showing Postfix queue, settings, and active SMTP sessions.
Terminal screenshot showing Postfix queue, settings, and active SMTP sessions.

Check the settings that affect outbound connections

For outbound Postfix delivery, the first controls to inspect are the custom transport in master.cf, the transport-specific destination concurrency settings, and connection cache behavior. The Postfix tuning notes are useful for separating process limits, concurrency limits, and rate controls.

Control

Scope

Why it matters

maxproc
service
Caps smtp client processes for that transport.
concurrency
destination
Limits parallel deliveries to a Postfix destination.
cache
session
Can keep idle SMTP sessions visible to the receiver.
delay
rate
Spaces deliveries when connection count alone is not enough.
Controls to inspect when a receiver enforces a strict connection cap.
A common mistake is to map many recipient domains to a custom transport and assume that one destination concurrency limit equals one provider-wide limit. That is not always true. If the receiver groups several domains under one provider limit, create a routing pattern that matches the receiver's counting model, then cap the total sender behavior under that model.
What Postfix controls
  1. Service: how many delivery agent processes a transport can run.
  2. Destination: how many parallel deliveries Postfix permits to one destination.
  3. Cache: whether an SMTP session stays open for reuse after a delivery.
What the receiver sees
  1. Source: total open TCP sessions from the same public IP.
  2. Provider: sessions across related MX hosts or branded domains.
  3. Timing: connection attempts that arrive close together during retry waves.

Use a strict-provider configuration pattern

When the receiver enforces a very small connection cap, I prefer a conservative pattern first: cap the custom transport in master.cf, set initial concurrency to 1, use a low destination concurrency, disable on-demand connection caching, and add a small delay if the provider also objects to rapid attempts.
master.cf custom transportstext
orange unix - - y - 2 smtp wanadoo unix - - y - 1 smtp
main.cf conservative sender controlstext
orange_initial_destination_concurrency = 1 orange_destination_concurrency_limit = 1 orange_destination_rate_delay = 2s orange_destination_recipient_limit = 10 wanadoo_initial_destination_concurrency = 1 wanadoo_destination_concurrency_limit = 1 wanadoo_destination_rate_delay = 2s wanadoo_destination_recipient_limit = 10 smtp_connection_cache_on_demand = no smtp_connection_cache_destinations = smtp_connection_cache_time_limit = 1s
This pattern intentionally gives up some throughput while you regain predictable behavior. After deferrals stop, increase one control at a time. If the receiver's official cap is 3, do not configure your own visible maximum at exactly 3 when cached sessions or other hosts can share the same source IP. Leave room for measurement error.
Connection budget for a receiver cap of 3
Use the receiver's per-source-IP cap as the real limit, not just the Postfix process count.
Safe test
1
One active connection while checking logs and socket state.
Normal cap
2
Two active connections with no cached idle sessions.
Risk zone
3
Three sessions leaves no room for cache, retries, or another sender.
Deferred
4+
Four or more sessions will trigger many strict receivers.

Test connection reuse as a separate variable

Connection reuse is helpful for throughput, but it can confuse strict remote connection accounting. A cached idle session is still an open session to the receiver. If the provider counts active plus idle sessions, a setup that looked safe as process count can exceed the provider's visible limit.
For a controlled test, temporarily disable on-demand caching and reduce cache lifetime, then send a small batch to the affected domains. Watch socket state at the same time. If deferrals disappear, the issue is not TLS itself. It is the total number of receiver-visible sessions during reuse and retry windows.
Short controlled testbash
postconf -e 'smtp_connection_cache_on_demand = no' postconf -e 'smtp_connection_cache_destinations =' postconf -e 'smtp_connection_cache_time_limit = 1s' postfix reload watch -n 1 "ss -tanp | egrep ':25|:587'"
If the provider says you exceeded the cap at an exact time, compare that timestamp to your socket count and queue manager logs. I would also check whether retries from earlier deferred mail created a second wave while the new batch was already sending.
  1. Match: provider timestamp, Postfix queue ID, and public source IP.
  2. Separate: active deliveries, cached sessions, and retry attempts in the evidence.

When concurrency is not the only cause

Some receivers use the phrase too many connections when the real trigger is repeated connection attempts, poor reputation, a sender that opens and drops sessions too quickly, or multiple deferred retries. If strict concurrency settings reduce but do not remove the errors, widen the diagnosis.
Run a delivery test after each Postfix change. Suped's email tester is useful here because you can send a real message through the same Postfix path and inspect headers, authentication, and delivery signals together. That does not replace server logs, but it helps confirm that the fix did not break the message itself.

Email tester

Send a real email to this address. Suped opens the report when the test is ready.

?/43tests passed
Preparing test address...
Also check the sending domain's authentication and reputation signals. A server-side throttling fix can stop 421 deferrals, but the same upgrade might have changed HELO, reverse DNS, DKIM signing, or SPF identifier matching. Suped's domain health checker gives a fast pass across DMARC, SPF, DKIM, and DNS basics before you call the incident closed.
  1. HELO: confirm it still uses a stable name with matching DNS.
  2. Reverse DNS: verify the PTR did not change during the OS migration.
  3. Queue waves: inspect old deferred mail before releasing a large backlog.
  4. Reputation: check blocklist and blacklist status if throttling persists.

Validate mail authentication after the Postfix fix

The Postfix fix is complete only when the server stays under the receiver's connection cap and the mail still passes authentication. Queue tuning can change delivery timing, but OS and package upgrades can also alter signing services, milter order, interface binding, or sender identity. Those changes show up in DMARC reporting before they show up in a user complaint.
Suped is practical for this stage because it brings DMARC, SPF, DKIM monitoring, hosted SPF, hosted DMARC, MTA-STS, blocklist monitoring, and alerts into one place. For this specific incident, I would use Suped to confirm that the upgraded Postfix server still appears as an expected source, that authentication pass rates stay steady, and that new failures are tied to a real sender rather than a spoofed source.
Issues page showing top issues, verified sources, unverified sources, and authentication pass rates
Issues page showing top issues, verified sources, unverified sources, and authentication pass rates
For teams managing several domains or client tenants, Suped's MSP and multi-tenancy dashboard is also useful after a mail server upgrade because the same Postfix change can affect unrelated domains differently. Continuous DMARC monitoring gives you the post-change evidence: which sources passed, which failed, and what to fix next.

A step-by-step recovery runbook

When I need a clean recovery, I use a short runbook and avoid changing five Postfix settings at once. The order matters because each step tests a different failure mode.
  1. Freeze: stop large releases to the affected provider until the active session count is known.
  2. Count: measure open SMTP sockets from every host using the same public IP.
  3. Cap: set strict custom transport limits below the receiver's stated cap.
  4. Disable: turn off on-demand connection caching for the affected route while testing.
  5. Retest: release a small batch and compare receiver deferrals with socket counts.
  6. Validate: confirm SPF, DKIM, DMARC, DNS, and reputation signals after delivery stabilizes.
If you still see deferrals after those changes, compare the symptom with related connection failures. A refusal at connect time has a different path than a provider-side concurrency deferral, so the next diagnostic branch is often connection refused errors rather than concurrency tuning.
For retry behavior, review the queue settings separately. Changing retry timing can reduce bursts after a backlog, but it should not be used to hide a provider cap that the active connection count still exceeds. A focused guide on Postfix retransmission timing is the better next step when deferrals happen in retry waves.

Views from the trenches

Best practices
Capture postconf, master service limits, logs, and socket counts before changing settings.
Treat a provider's cap as a source-IP budget, including cached sessions and retries.
Test only one setting at a time so the fix can be explained and safely rolled back.
Common pitfalls
Tuning inbound smtpd limits will not change outbound smtp client concurrency at all.
Mapping many domains to one route does not always equal one provider-wide cap in practice.
Queue retries after an upgrade can create bursts that look like new concurrency.
Expert tips
Disable on-demand cache briefly to prove whether idle sessions affect the receiver.
Keep configured limits below the receiver cap when NAT or extra senders share an IP.
Use provider timestamps to match deferrals with exact Postfix queue and socket state.
Marketer from Email Geeks says complex Postfix connection issues need the exact configuration and error text before a useful diagnosis is possible.
2021-12-03 - Email Geeks
Marketer from Email Geeks says the shared configuration did not show an obvious mistake, so logs and upstream timing mattered more than guessing.
2021-12-03 - Email Geeks

What I would change first

I would not start with smtpd junk command settings. I would first prove the receiver-visible connection count, reduce the affected custom transports below the provider's stated cap, disable on-demand SMTP connection caching during the test, and add a small destination rate delay if the receiver still reports rapid attempts.
Once delivery stabilizes, bring performance back carefully. Increase one limit, wait through a retry cycle, and compare logs with live socket counts. For the authentication and reputation side, Suped gives you the monitoring layer that Postfix does not have: DMARC source visibility, real-time alerts, hosted SPF, hosted DMARC, hosted MTA-STS, SPF flattening, and blocklist (blacklist) monitoring across domains.
The practical target is not maximum throughput on day one after the upgrade. The target is predictable delivery under the receiver's published or confirmed limits, with enough monitoring to catch authentication or reputation changes caused by the same migration.

Frequently asked questions

DMARC monitoring

Start monitoring your DMARC reports today

Suped DMARC platform dashboard
What you'll get with Suped
Real-time DMARC report monitoring and analysis
Automated alerts for authentication failures
Clear recommendations to improve email deliverability
Protection against phishing and domain spoofing