A sender gets 550 5.1.1 <user@domain>: Recipient address rejected: User unknown in local recipient table (or the virtual mailbox or relay variant). Postfix rejected the recipient at SMTP RCPT TO time, before queueing, because the address was not found in the map for that address class. This validation is controlled by smtpd_reject_unlisted_recipient (default: yes).
The problem is either that a legitimate recipient is missing from the map, or that the domain is in the wrong address class and Postfix is checking the wrong map. Before changing restrictions or disabling validation, identify which map Postfix consulted, test the lookup with postmap -q, and reconcile the map against your authoritative directory. The reject string identifies the address class.
What this means
Each address class has its own recipient validation map. The three reject strings and their corresponding maps:
- “User unknown in local recipient table” - Domain is in
mydestination. Postfix checkslocal_recipient_maps(default:proxy:unix:passwd.byname $alias_maps). - “User unknown in virtual mailbox table” - Domain is in
virtual_mailbox_domains. Postfix checksvirtual_mailbox_maps. - “User unknown in relay recipient table” - Domain is in
relay_domains. Postfix checksrelay_recipient_maps.
If a map parameter is empty, Postfix accepts all recipients for that class without checking. This is dangerous on internet-facing systems because it produces backscatter.
The key diagnostic question: which address class does the rejected domain belong to, and does the corresponding map contain the recipient?
flowchart TD
A["Recipient user@domain rejected"] --> B["Which reject string?"]
B -->|"local recipient table"| C["Domain in mydestination"]
B -->|"virtual mailbox table"| D["Domain in virtual_mailbox_domains"]
B -->|"relay recipient table"| E["Domain in relay_domains"]
C --> F["Map: local_recipient_maps"]
D --> G["Map: virtual_mailbox_maps"]
E --> H["Map: relay_recipient_maps"]
F --> I["Test: postmap -q user@domain map"]
G --> I
H --> ICommon causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Domain in wrong address class | A domain that should be relayed or hosted as virtual mailbox is listed in mydestination, so Postfix checks local_recipient_maps instead of the correct map | postconf -h mydestination virtual_mailbox_domains relay_domains |
| Stale or incomplete recipient map | User exists in the directory but not in the Postfix map; .db file not rebuilt after the directory changed | postmap -q user@domain against the map, then check .db mtime |
| Map backend unresponsive or slow | Valid users intermittently rejected; smtpd processes accumulate; delivery latency rises | Time a postmap -q query against network-backed maps (LDAP, SQL) |
| Dictionary attack | Spike of “User unknown” rejections from few source IPs; low legitimate message volume | Count rejects by client IP in mail logs |
| Map source out of sync | Recent provisioning changes not propagated to the map file or query result | Compare map contents against directory export |
Quick checks
# Show which recipient maps are configured
postconf -h local_recipient_maps virtual_mailbox_maps relay_recipient_maps
# Show domain-to-address-class assignments
postconf -h mydestination virtual_mailbox_domains relay_domains
# Confirm smtpd_reject_unlisted_recipient is enabled
postconf -h smtpd_reject_unlisted_recipient
# Find recent rejections (path varies: mail.log on Debian, maillog on RHEL)
grep 'User unknown' /var/log/mail.log | tail -20
# or: grep 'User unknown' /var/log/maillog | tail -20
# Count rejections by source IP in the last hour
grep "$(date '+%b %e %H' -d '1 hour ago')" /var/log/mail.log \
| grep 'User unknown' \
| grep -oE 'client=[^]]+\[[0-9.]+' \
| sort | uniq -c | sort -rn | head -10
# Test a specific map lookup directly
postmap -q testuser@example.com hash:/etc/postfix/relay_recipients
# Check map file freshness (.db mtime for hash/btree maps)
stat /etc/postfix/relay_recipients.db
# Time a network-backed map query to check backend responsiveness
time postmap -q testuser@example.com mysql:/etc/postfix/mysql-virtual.cf
How to diagnose it
Extract the rejected address, domain, and reject string from the logs. The reject line includes
to=<user@domain>and the specific reject string (“local recipient table”, “virtual mailbox table”, or “relay recipient table”). The string identifies the address class.Verify the domain’s address class. Check whether the domain appears in
mydestination,virtual_mailbox_domains, orrelay_domains:postconf -h mydestination virtual_mailbox_domains relay_domainsA domain in the wrong class is the most common cause. A relay domain accidentally left in
mydestinationcauses Postfix to checklocal_recipient_maps(UNIX passwd and aliases) instead ofrelay_recipient_maps, rejecting every valid relay recipient.Test the map lookup directly. Identify the map from
postconf, then query it withpostmap -qusing the exact recipient address:postconf -h relay_recipient_maps postmap -q user@domain hash:/etc/postfix/relay_recipientsIf
postmap -qreturns nothing, the map does not contain the recipient. If it returns a value but Postfix still rejects, verify you tested the same map type:path frompostconfoutput (including anyproxy:prefix) and that Postfix has reloaded after recent changes.Verify the user exists in the authoritative source. Check the directory, database, or passwd file directly. If the user does not exist there, the rejection is legitimate.
Check map freshness. For hash or btree maps, compare the
.dbfile mtime against the last provisioning change:stat /etc/postfix/relay_recipients.dbIf the
.dbpredates recent changes, rebuild it.Rule out backend slowness for network-backed maps. Time the query:
time postmap -q user@domain ldap:/etc/postfix/ldap-recipients.cfQuery times above 500ms indicate backend latency that can cause intermittent rejections or smtpd starvation under load.
Determine if this is a spike or a persistent issue. A sudden increase in “User unknown” rejections from few source IPs, with low overall legitimate volume, is a dictionary attack, not a configuration problem. Count rejects by client IP to distinguish.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
| Reject count by category | Distinguishes dictionary attacks from configuration drift | Sudden spike in RCPT rejects, especially from a single source IP |
| Bounce rate | Sustained rejections of valid recipients generate bounces to senders | Bounce rate above 1% sustained |
| Map query latency | Slow network-backed maps cause intermittent rejections and smtpd accumulation | Query time above 500ms for LDAP or SQL maps |
Map freshness (.db mtime) | Stale maps reject valid users added after last rebuild | .db mtime predates last directory provisioning change |
| smtpd process utilization | Slow map queries hold smtpd processes open | Process count approaching maxproc with low throughput |
| Per-client connection rate | High rate from single IP indicates address harvesting | More than 100 connections/minute from one source |
Fixes
Domain classified into the wrong address class
The most common cause. A domain that should be relayed or hosted as a virtual mailbox is in mydestination.
Remove the domain from mydestination and add it to the correct class parameter. Then ensure the corresponding map contains valid recipients for that domain.
# Review current assignments before making changes
postconf -h mydestination relay_domains virtual_mailbox_domains
# WARNING: postconf -e replaces the entire parameter value.
# Review your current settings and adjust accordingly.
postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'
postconf -e 'relay_domains = example.com, other.example.com'
# Ensure relay_recipient_maps is populated
postconf -e 'relay_recipient_maps = hash:/etc/postfix/relay_recipients'
postfix reload
After reloading, test with postmap -q and send a test message to confirm acceptance.
Stale or incomplete recipient map
The user exists in the authoritative directory but the Postfix map was not rebuilt after the directory changed.
# Rebuild a hash map from its source file
postmap /etc/postfix/relay_recipients
# Verify the lookup now succeeds
postmap -q user@domain hash:/etc/postfix/relay_recipients
For maps generated by a script or sync job, verify the generation process ran and check for errors in its output. Automate the rebuild on a cron schedule or trigger it from the provisioning system.
Network-backed map unresponsive or returning empty results
For LDAP or SQL-backed maps, the backend may be slow, returning unexpected empty results, or timing out.
Check the backend directly. Verify the query in the map configuration file returns results when run manually. Review connection parameters and timeouts in the map definition file (e.g., ldap-recipients.cf or mysql-virtual.cf). Ensure the LDAP or SQL server has adequate capacity and replication is current.
If the backend is intermittently slow, configure timeouts in the map definition to prevent smtpd from hanging indefinitely.
Dictionary attack (spike of rejections from one source)
A burst of “User unknown” rejections from few IPs hitting random or sequential addresses. The rejections are working correctly.
Rate-limit the attacking source and consider pre-queue filtering:
# Limit recipients per client (default: 0, disabled)
postconf -e 'smtpd_client_recipient_rate_limit = 100'
# Enable postscreen for pre-queue zombie filtering
# WARNING: Enabling postscreen changes how Postfix handles all incoming
# connections. Review postscreen(8) and configure postscreen_* parameters
# before enabling in production.
postconf -e 'postscreen_enable = yes'
postfix reload
Also consider fail2ban or equivalent IP-based blocking for sources generating excessive rejections.
Do not disable recipient validation on internet-facing systems
Setting local_recipient_maps (or relay_recipient_maps) to empty disables recipient validation for that class. Postfix will accept mail for any address, then generate bounce messages to the envelope sender. On internet-facing systems, forged sender addresses mean these bounces go to innocent third parties. This is backscatter, and it gets your IP listed on blocklists.
If you are tempted to set local_recipient_maps = to stop rejections, the correct fix is to populate the map with valid recipients, not to disable validation.
Prevention
- Automate map rebuilds. Synchronize recipient maps from the authoritative directory on a schedule or via event-triggered updates.
- Validate domain classification after config changes. After any change to
mydestination,virtual_mailbox_domains, orrelay_domains, verify each domain maps to the correct recipient validation map. - Monitor reject rates by category. Track “User unknown” rejections separately from relay denials, SPF failures, and other reject types.
- Include
postmap -qin health checks. Test known valid recipients as part of monitoring or pre-deployment validation. - Monitor network-backed map query latency. Set thresholds on LDAP and SQL query times to catch backend degradation before it causes smtpd starvation.
- Use postscreen and rate limiting. Filter zombies before SMTP proper to prevent dictionary attacks from consuming smtpd resources.
How Netdata helps
- Correlate reject count spikes with per-client connection rates to distinguish dictionary attacks from configuration drift. A spike from one IP at 3 a.m. is an attack; a steady increase across all senders after a config change is drift.
- Track bounce rate alongside reject patterns. If valid recipients are being rejected, senders see bounces; sustained bounce rates above 1% indicate reputation risk.
- Monitor smtpd process utilization against
maxproc. Slow map queries hold smtpd processes open; approaching the process limit with low throughput points to backend latency, not traffic volume. - Alert on map-related patterns. A spike in “User unknown” rejections for a domain that should be relayed, combined with normal delivery for other domains, isolates the problem to map or address-class configuration for that domain.
Related guides
- Postfix active queue saturation: hitting qmgr_message_active_limit
- Postfix backscatter storm: bounces to forged senders and blocklisting
- Postfix IP blocklisted: deliverability collapse and sender reputation
- Postfix bounce rate spike: 5xx failures, bad address lists, and reputation risk
- postfix check warnings: configuration drift and permission problems
- Postfix Connection refused: blocked port 25 and rejected outbound delivery
- Postfix Connection timed out: delivery deferrals to unreachable destinations
- Postfix content_filter backpressure: incoming queue growth when Amavis or Rspamd slows
- Postfix deferred queue growing: why mail piles up and how to drain it
- Postfix destination concurrency limit: tuning per-destination delivery
- Postfix DNS resolver failure: when a broken resolver defers mail to everyone
- Postfix flushing and clearing the deferred queue: postqueue and postsuper






