Mail is deferring to every destination. Gmail, Outlook, corporate partners, even your own relayhost. The master process is running, the queue manager is responsive, and the SMTP listener accepts connections. But the deferred queue keeps growing, and the deferral reasons point to DNS: “Host or domain name not found” or “Name service error for name=… type=MX: Host not found, try again.”

Postfix depends entirely on DNS for MX resolution, A/AAAA address lookups, reverse PTR verification, and DNSBL queries. It has no internal DNS cache. When the resolver breaks, deliveries defer rather than bounce. The deferral reason is often generic enough that operators chase the wrong problem.

The telltale sign is that all destinations are affected equally. A single bad destination monopolizing the queue produces a different pattern; see Postfix deferred queue growing for that case.

What this means

Postfix uses the system resolver for all DNS lookups. When running chrooted, it reads /var/spool/postfix/etc/resolv.conf, not /etc/resolv.conf. The startup script copies /etc/resolv.conf into the chroot only at Postfix startup. If DNS servers change after Postfix starts (common in cloud environments where resolvers are reassigned), the chroot copy becomes stale. Postfix keeps querying dead resolvers while dig from the shell works perfectly because the shell reads the live /etc/resolv.conf.

A slow resolver and a dead resolver produce different symptoms:

  • Slow resolver: DNS queries eventually succeed but take several seconds. The resolver library’s own timeout expires before the answer arrives. Some deliveries succeed, others defer intermittently. The pattern looks like network flakiness or destination problems.
  • Dead resolver: Queries return SERVFAIL or no answer at all. Every delivery defers uniformly across all destinations. If the resolver incorrectly returns NXDOMAIN for valid domains, Postfix bounces rather than defers, which is a different symptom.

Both look like “mail is slow” from the outside. The distinction matters because the fixes differ: a slow resolver needs timeout tuning or resolver capacity work, a dead resolver needs the resolver itself fixed or replaced.

flowchart TD
    A[All destinations deferring] --> B{Reason: Host not found?}
    B -->|No| C[Check TLS or connection errors]
    B -->|Yes| D[Test DNS from MTA shell]
    D -->|Fails| E[Resolver down or unreachable]
    D -->|Works| F[Check chroot resolv.conf]
    F --> G{Stale vs etc resolv.conf?}
    G -->|Stale| H[Postfix restart copies fresh]
    G -->|Same| I[Check AAAA-only failures]

Common causes

CauseWhat it looks likeFirst thing to check
Stale chroot resolv.confdig works from shell but Postfix defers everythingdiff /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
Resolver process down or overloadedDNS queries from shell also fail or are very slowsystemctl status systemd-resolved or pgrep -a named
IPv6 AAAA lookup failureDeferrals show type=AAAA: Host not found for valid domainsgrep 'type=AAAA' /var/log/mail.log
Negative DNS cacheFailures persist after resolver is fixedFlush cache: resolvectl flush-caches or rndc flush
Startup race conditionPostfix started before network was ready; chroot resolv.conf emptyCompare mtime of chroot copy vs Postfix start time
Aggressive resolver timeoutIntermittent deferrals to high-latency MX targetsCheck options timeout: in resolv.conf

Quick checks

# Check deferred queue size
find /var/spool/postfix/deferred -type f | wc -l

# Deferral reasons from recent logs (systemd journal)
journalctl -t postfix/smtp --since '5 min ago' --no-pager 2>/dev/null \
  | grep 'status=deferred' \
  | grep -oE 'Host not found|Name service error|type=MX|type=AAAA|type=A' \
  | sort | uniq -c

# If using syslog files instead of journalctl:
# tail -10000 /var/log/mail.log | grep 'status=deferred' | grep -oE '...' | sort | uniq -c

# Test DNS resolution directly from MTA
dig +short gmail.com MX

# Test with the resolver configured in resolv.conf
dig @$(awk '/nameserver/ {print $2; exit}' /etc/resolv.conf) gmail.com MX

# Compare chroot resolv.conf with system resolv.conf
diff /etc/resolv.conf /var/spool/postfix/etc/resolv.conf

# Check resolver process health
systemctl status systemd-resolved 2>/dev/null || pgrep -a named

# Check Postfix DNS lookup configuration
postconf -h smtp_host_lookup inet_protocols

# Check for IPv6-specific deferrals
grep 'type=AAAA' /var/log/mail.log | tail -20

# Measure DNS latency to a common destination
time dig +short outlook.com MX

How to diagnose it

1. Confirm the pattern is DNS-related, not destination-specific. If all destinations are deferring with “Host not found” or “Name service error,” DNS is the prime suspect. If only one domain is affected, the problem is likely elsewhere. See Postfix Host or domain name not found for the broader error catalog.

2. Test DNS from the MTA shell. Run dig +short gmail.com MX. If this fails or takes more than 1-2 seconds, the resolver itself is the problem. If it works, the issue is likely the chroot resolv.conf or an IPv6-specific failure.

3. Check the chroot resolv.conf. Run diff /etc/resolv.conf /var/spool/postfix/etc/resolv.conf. If they differ, Postfix is using stale resolver addresses. The common scenario: /etc/resolv.conf was updated (new nameserver after cloud instance restart) but Postfix has not been restarted, so the chroot copy still references the old resolver.

4. Check for IPv6 AAAA failures. With inet_protocols = all (the default), Postfix performs AAAA lookups for every MX target. If the resolver returns SERVFAIL for AAAA queries, or the server has no IPv6 route, Postfix defers with type=AAAA: Host not found, try again. The domain has valid A records, but the AAAA failure blocks delivery. Check with grep 'type=AAAA' /var/log/mail.log.

5. Check resolver process health. Is systemd-resolved running? Is named consuming high CPU? Is nscd serving stale negative cache entries? The resolver may be alive but degraded, returning slow or intermittent responses.

6. Check for negative DNS cache persistence. If a caching resolver (systemd-resolved, dnsmasq, nscd, unbound) cached a SERVFAIL or NXDOMAIN response while the upstream was broken, those cached failures persist until their TTL expires. Postfix will keep seeing the failure even after you fix the upstream resolver. Restarting Postfix does not clear the DNS cache because Postfix does not have one.

Metrics and signals to monitor

SignalWhy it mattersWarning sign
Deferred queue growth rateEarliest indicator of systemic delivery failureSustained positive growth over 5+ minutes
Delivery rate vs injection rateConfirms whether mail is actually leavingDelivery near zero with normal injection
DNS resolver latencySlow resolver causes intermittent timeoutsQuery latency p99 above 1 second
DNS resolver error rateSERVFAIL or timeout rate from the resolverAny sustained non-zero error rate
Deferral reason distributionReveals whether failures are DNS-specificSpike in “Host not found” or “Name service error”
Active queue sizeLow active queue with high deferred suggests upstream failureActive queue not growing despite deferred growth

Fixes

Stale chroot resolv.conf

Restart Postfix to trigger the resolv.conf copy into the chroot:

# Verify the difference first
diff /etc/resolv.conf /var/spool/postfix/etc/resolv.conf

# Restart triggers the startup script to copy fresh resolv.conf
systemctl restart postfix

# Verify the copy is now current
diff /etc/resolv.conf /var/spool/postfix/etc/resolv.conf

After restart, the queue manager scans all queues, which can take minutes on large deferred queues. Delivery will not resume immediately. For draining strategies, see Postfix flushing and clearing the deferred queue.

If this recurs frequently (cloud environments with dynamic resolvers), consider whether Postfix should run chrooted at all, or add a systemd dependency that restarts Postfix when /etc/resolv.conf changes.

Resolver process failure

Fix the resolver first. Postfix will recover as the queue manager retries deferred messages.

If the local resolver is systemd-resolved and it is stuck, restarting it is the immediate fix. If upstream DNS servers are unreachable due to network partition, adding a fallback resolver to /etc/resolv.conf and restarting Postfix (to refresh the chroot copy) is the emergency workaround.

After fixing the resolver, flush any negative cache:

# Flush systemd-resolved cache
resolvectl flush-caches

# Or flush BIND cache if using named
rndc flush

# Or restart nscd if present
systemctl restart nscd 2>/dev/null

IPv6 AAAA lookup failures

If your server has no functional IPv6 connectivity, disable AAAA lookups to eliminate the failure path:

# Current setting
postconf -h inet_protocols

# Restrict to IPv4 only
postconf -e 'inet_protocols = ipv4'
postfix reload

Common scenario: cloud VPCs with IPv6 routing that exists but is broken, or containers with incomplete IPv6 stacks. The tradeoff is losing the ability to deliver to IPv6-only MX hosts, which are still rare but increasing.

Aggressive resolver timeout

If resolv.conf contains tight timeout settings like options timeout:1 attempts:1, DNS queries that take more than 1 second will fail. This is common with high-latency MX targets (Outlook, Office 365) where query times can exceed 2 seconds. Increase the timeout:

# In /etc/resolv.conf
options timeout:3 attempts:2

After changing /etc/resolv.conf, restart Postfix to refresh the chroot copy.

Negative DNS cache persistence

If deferrals persist after the resolver is fixed, the caching resolver may still be serving stale SERVFAIL responses. Flush the cache using the commands above, then wait for the queue manager retry cycle to pick up the now-successful lookups.

Old deferred messages may not retry immediately due to exponential backoff. The default maximal_backoff_time is 4000s (about 67 minutes), so some messages may sit in deferred even after the fix. To force immediate retry:

# Force retry of all deferred messages.
# Postfix rate-limits this internally, but on very large queues
# expect a temporary spike in outbound connections.
postqueue -f

Prevention

  • Monitor the resolver independently of Postfix. Teams monitor queues, delivery rates, and SMTP responsiveness, but not DNS resolver latency and failure rate. When the resolver degrades, the first visible symptom is Postfix deferring mail, and operators waste time inspecting Postfix instead of the resolver.
  • Track DNS query latency, not just availability. A resolver that answers in 50ms one minute and 3000ms the next is failing intermittently. Monitor p99 latency of DNS queries from the MTA host.
  • Validate the chroot resolv.conf after any network change. Cloud instances that get new resolver IPs on reboot are the most common source of stale chroot copies. Add a check to boot scripts that compares the two files after Postfix starts.
  • Flush negative cache after any DNS incident. Cached SERVFAIL responses extend an outage by their TTL even after the upstream problem is resolved. Make this a standard step in your DNS incident runbook.
  • Set inet_protocols = ipv4 proactively if you lack IPv6. Do not wait for AAAA deferrals to surface the problem.

How Netdata helps

  • DNS query latency and error rate collected per-second from the MTA host, independent of Postfix logs. Correlating a latency spike with the start of deferred queue growth pinpoints the resolver as root cause.
  • Deferred queue depth and growth rate tracked over time, showing the exact moment delivery started failing and whether it correlates with a DNS event or network change.
  • Delivery rate vs injection rate presented together, making the “mail is not leaving” pattern immediately visible without manual log parsing.
  • System-level resolver metrics (CPU usage of systemd-resolved or named, open file descriptors, memory) that reveal resolver degradation before it causes Postfix deferrals.