2026.10 / lookup backends 073
Docker Mailserver 451 4.3.0 “Temporary lookup failure”
An SMTP client reaches Docker Mailserver, but Postfix answers with 451 4.3.0 Temporary lookup failure. The word temporary matters: Postfix could not get a trustworthy answer from a lookup table or policy service, so it asks the sender to retry instead of accepting or permanently rejecting the message.
The useful clue is usually not the 451 line itself. It is the warning immediately before it: a map path, map type, socket, hostname, permission error, connection refusal, or malformed query. Find that dependency first. Rebuilding every map, restarting every service, or changing DNS blindly can destroy evidence without fixing the failed lookup.
A temporary lookup failure is a safety response, not a diagnosis. Identify the exact lookup, reproduce it directly, then repair the persistent source that creates it.
What Postfix may be trying to look up
Postfix uses key-value lookups for recipient validation, aliases, sender ownership, transport selection, access rules, and other routing decisions. Docker Mailserver can supply those answers from generated local files or from an external provisioner such as LDAP. A policy service, including a quota check, may also be consulted during the SMTP conversation.
| Log clue | Likely boundary | First direct test |
|---|---|---|
virtual_alias_maps map lookup problem | Alias map or its backend | Query the exact map for the logged address |
virtual_mailbox_maps map lookup problem | Mailbox recipient map | Query the exact recipient through the effective map |
sender_login_maps map lookup problem | Authenticated sender ownership | Query the envelope sender and compare the SASL login |
connect to ...: Connection refused | LDAP, SQL, socketmap, or policy service | Test name resolution, route, port, and service health from the mail container |
open database ...: Permission denied | Local source or compiled map | Inspect the exact file and parent-directory access inside the container |
unsupported dictionary type | Map type absent from this Postfix build | Compare the configured type with postconf -m |
1. Preserve one complete failure
Collect a short current log window and keep it private:
docker compose logs --since 10m mailserver
For one failed attempt, record the timestamp, Postfix process name, queue ID if one exists, SMTP stage, envelope address, full 451 response, and every adjacent warning. Redact real addresses, hostnames, addresses, credentials, and message identifiers before sharing excerpts.
The SMTP stage narrows the search. A failure during RCPT TO often involves recipient, domain, alias, access, or quota policy lookups. A failure after authenticated MAIL FROM can involve sender-login restrictions. A queued delivery failure may instead involve transport or next-hop lookup data.
2. Read the effective lookup configuration
Do not infer the running configuration from a Compose file alone. Ask Postfix which maps and restrictions are active:
docker compose exec mailserver postconf \
virtual_mailbox_domains virtual_mailbox_maps virtual_alias_maps \
smtpd_sender_login_maps transport_maps \
smtpd_recipient_restrictions smtpd_sender_restrictions
Then list map types supported by this image:
docker compose exec mailserver postconf -m
Keep the output private because lookup configuration can include internal names, bind identities, and file locations. Match the warning to one returned type:table value. Do not substitute a path from another DMS version or a forum post.
3. Query the failing map directly
Postfix’s official lookup-table guide recommends postmap -q for testing a key against the same table used by Postfix. Use the exact map value from postconf:
docker compose exec mailserver \
postmap -q [email protected] '<type:table-from-postconf>'
Interpret the result carefully:
- A valid value: the map works for that key now. Compare timing, process, and any intermittent backend or network failure.
- No output with exit success: the key was not found. That is different from a temporary backend error; verify address case, provisioner data, and the table’s documented search order.
- An explicit error: its map type, path, socket, permission, or connection detail is the branch to repair.
Test only representative keys you control. A lookup result can expose an internal mailbox, alias target, or routing destination.
4. If it is a local file map, inspect source and generated state
With the DMS file provisioner, accounts and aliases in the persistent configuration are transformed into effective Postfix data. Confirm the supported account view first:
docker compose exec mailserver setup email list
docker compose exec mailserver setup alias list
Then inspect metadata for only the path named in the warning:
docker compose exec mailserver \
stat '<exact-map-path-from-the-log>'
Check that the source exists, the generated database matches the expected table type, every parent directory is traversable by the effective service identity, and the filesystem is writable during generation. Also check host bytes and inodes before rebuilding a map: Postfix warns that an interrupted overwrite caused by a full disk can leave a local database unusable.
Do not fix a generated file by making the entire configuration tree world-writable. Repair the narrow source ownership or mount mode, preserve a copy for evidence, and let the supported DMS startup path regenerate effective configuration.
5. If it is LDAP, SQL, socketmap, or a policy service
External lookups add four failure layers: configuration, container DNS, network reachability, and backend behavior. From inside the mail container, verify them in that order:
docker compose exec mailserver getent hosts directory.example.internal
docker compose exec mailserver \
bash -lc 'timeout 5 bash -c "</dev/null >/dev/tcp/directory.example.internal/389"'
Replace the placeholder with the internal service name and port from your deployment; never publish a real internal address. Docker documents that containers on the same user-defined network can resolve one another by container name or network alias. A host-only name, the wrong network, an internal-only network without the required route, or 127.0.0.1 used for a different container will fail from DMS even if a host-side test succeeds.
For LDAP or SQL, also verify that the configured backend type appears in postconf -m, the backend is healthy, the bind identity can perform the required narrow read, TLS trust is valid where enabled, and the query returns one correctly shaped result. Do not print bind passwords or connection URIs. For a Unix socket or quota policy service, inspect the socket path, owner, mode, and the target service log at the same timestamp.
6. Distinguish a missing key from a failed backend
This distinction prevents unsafe recipient fixes:
- Missing mailbox or alias: the lookup mechanism answered normally but found no key. Provision the intended address or alias through the active DMS provisioner.
- Failed lookup: the mechanism could not answer reliably. Repair its file, permissions, supported map type, socket, DNS, network, certificate, credentials, query, or backend availability.
If the mechanism works and Postfix returns User unknown in virtual mailbox table, follow the recipient-map guide. If the authenticated sender exists but is not authorised for the envelope address, use the sender ownership guide. Turning either case into a catch-all or disabling recipient checks is not a lookup repair.
7. Apply the repair at the durable source
Docker Mailserver documents persistent Postfix overrides in docker-data/dms/config/postfix-main.cf; it applies them during container startup. Account-provisioner settings, Compose networks, mounted configuration, and backend definitions likewise belong in their deployment source—not in an interactive edit inside the running container.
After correcting the smallest proven fault, retain the pinned image and persistent mail volumes, then recreate the service so DMS startup scripts generate configuration from a clean image:
docker compose up -d --force-recreate mailserver
Do not use down -v. Do not delete the mail store. Do not upgrade the image in the same change unless the unsupported map type is the demonstrated cause and the upgrade has its own backup and rollback plan.
8. Verify the lookup, SMTP outcome, and delivery
- Repeat the exact
postmap -qtest and confirm the intended result. - Repeat
postconfand prove the effective map still points at the intended durable source. - Send one controlled external message to an address you own.
- Trace its queue ID through acceptance and final mailbox delivery.
- Confirm the 451 and its preceding lookup warning do not recur.
- Run a negative test for one nonexistent recipient; it should still be rejected according to policy rather than accepted broadly.
- Recheck after the next normal recreation so the fix is proven persistent.
If the backend was intermittent, one successful message is weak evidence. Observe several normal lookup cycles and monitor backend latency, connection errors, and container restarts over a bounded period.
Repairs to avoid
- Retrying the whole queue before the lookup is healthy: this adds noise and can repeatedly defer every affected message.
- Disabling recipient validation: it can accept mail that later bounces, creating backscatter risk.
- Making configuration world-readable or writable: lookup files and backend configs may contain sensitive account or bind information.
- Hard-coding a container address: container addresses can change; repair the shared network and service name instead.
- Editing
/etc/postfix/main.cfonly inside the container: the change disappears on recreation and leaves the source of truth wrong. - Assuming every 451 is DNS: the adjacent warning may identify a local database, unsupported map type, socket, permission, or policy-service failure.
- Deleting mail or configuration volumes: that removes state and evidence without proving the lookup boundary.
Compact diagnosis order
- Capture one complete 451 event with adjacent warnings and SMTP stage.
- Map the warning to the effective
type:tableor policy service. - Confirm that this Postfix build supports the map type.
- Query the exact map and key directly.
- For files, check source, generated database, ownership, mounts, bytes, and inodes.
- For services, test container DNS, shared network, port, health, TLS, access, and query shape.
- Repair the smallest persistent source and recreate DMS cleanly.
- Verify positive delivery, negative recipient behavior, no repeated warning, and persistence.
Authoritative references: Docker Mailserver’s debugging guide explains log collection and clean recreation; its account-management overview describes account, alias, and Postfix lookup responsibilities; its Postfix override guide documents durable overrides; Postfix’s official lookup-table overview documents table types and direct postmap -q tests; and Docker’s networking guide documents container DNS and user-defined networks. Match every command to the image, provisioner, and backend you actually operate.