Use Postfix error and retry Services Without Guessing
You will learn what Postfix's error(8) delivery agent actually does, how its error and retry services differ, and how to inspect a change before it affects queued mail. This is an administration guide for Postfix 3.8.6, the version installed on the machine used for these examples.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes for an inspection. A configuration change needs a maintenance window, access to the Postfix administrator account, and a plan for checking mail logs afterwards. The examples do not submit or delete mail.
Checkpoint 1: recognise the boundary
error(8) is not a user-facing command for sending a test message. It is a Postfix-internal delivery agent started by the master(8) process manager. The queue manager gives it a queue file, sender, recipients, and a next-hop value that describes why delivery cannot proceed.
The agent does not contact the network. It reports the result to Postfix's bounce(8), defer(8), or trace(8) daemon. Running error from a shell is therefore the wrong test and bypasses the internal protocol it expects. Inspect the configured service instead:
postconf -M error/unix
postconf -M retry/unix
On the inspected installation, both services use the error daemon:
error unix - - y - - error
retry unix - - y - - error
The final field is the daemon name. The first field is the service name that gives the daemon its behaviour. That distinction is the detail most likely to cause confusion.
Checkpoint 2: choose bounce or defer
When the service is named error, Postfix bounces all recipients in that delivery request. A bounce tells the sender that delivery has failed. When the same daemon is exposed through a service named retry, Postfix defers all recipients instead, leaving them eligible for later delivery attempts.
These are different operational outcomes even though the daemon column is identical. Use the retry service when the condition is temporary and a later attempt is useful. Use the error service when the queue manager has been told that delivery should fail. Do not rename a service casually: changing the service name can change recipient notifications and queue lifetime.
The next-hop text is used as the reason for non-delivery. It may begin with an RFC 3463 enhanced status code such as 4.0.0 or 5.0.0. If no compatible code is supplied, the agent uses a default temporary or permanent code as appropriate. Treat that text as mail-facing diagnostic content: keep it accurate, brief, and free of secrets.
Checkpoint 3: inspect the live configuration
Use ordinary privileges for these read-only checks:
postconf mail_version
postconf -h config_directory
postconf -h queue_directory
postconf -M error/unix
postconf -M retry/unix
Expected values on this installation include 3.8.6, /etc/postfix, and /var/spool/postfix. Your machine may use different paths. Trust the output from your own host rather than copying those paths into a script.
For the complete service definition, inspect master.cf in the reported configuration directory. A master.cf logical line has eight whitespace-separated fields. Continuation lines begin with whitespace. The service type for these entries is unix, which means the service is reachable through a UNIX-domain socket below the queue directory, not through a TCP port.
Do not edit a generated copy or assume that a commented example is active. Check the effective definition with postconf -M after locating the file. This catches duplicate service lines, where the last definition for the same service name and type wins.
Checkpoint 4: change only with a recovery path
Warning
Editing master.cf changes mail delivery. A mistaken service name can turn a temporary problem into immediate bounces, or leave messages deferred when they should fail. Preserve a copy of the file and record the original line before editing. Elevated privileges are required to change the system configuration.
sudo cp -p /etc/postfix/master.cf /etc/postfix/master.cf.before-error-change
sudoedit /etc/postfix/master.cf
Keep the daemon field as error unless you have a documented reason to select another Postfix service. If your change is intended to defer rather than bounce, make the service name and the routing decision agree with that intention. Do not add shell redirections, pipes, or quoted arguments to a service line: the master(5) format does not interpret them as a shell would.
Before reloading, ask Postfix to show the effective entries again:
postconf -M error/unix
postconf -M retry/unix
If the output is not exactly what you intended, stop and restore the saved file:
sudo cp -p /etc/postfix/master.cf.before-error-change /etc/postfix/master.cf
That recovery command changes state but does not reload Postfix. Check the restored definitions first, then reload when you are satisfied that the original service lines are back.
Checkpoint 5: reload and verify
Postfix daemons run for a limited time, so changes in main.cf are picked up as processes are replaced. A master.cf change requires an explicit reload. This is an elevated, service-affecting operation:
sudo postfix reload
After the reload, verify the service definitions and inspect the mail log used by your operating system. The error agent documents transactions and problems through syslogd(8) or postlogd(8). Search for the relevant queue ID and service name rather than relying on a single generic error message. If the change was meant to defer mail, confirm that the queue remains deferred; if it was meant to bounce mail, confirm that Postfix generated the expected delivery status report.
Do not use a real recipient as a quick destructive test. A bounce cannot be withdrawn, and a deferred message can produce repeated delivery attempts. Use an existing, controlled queue event or a separately approved test workflow, then remove no queue files by hand. Queue files are Postfix's responsibility.
Common traps
- Calling the binary directly:
error(8) expects a request frommaster(8), so a shell invocation is not a meaningful delivery test. - Reading the last field only: both installed entries end in
error, but the service name at the start determines bounce versus defer behaviour. - Assuming a default status code: the reason may carry an enhanced status code. Without one, Postfix chooses a default code based on the failure path.
- Forgetting the reload: editing
master.cfdoes not make runningmasterprocesses reread it untilpostfix reloadis executed. - Changing privilege or chroot fields casually: the documented service is already a low-privilege, chroot-capable internal service. Altering those fields needs a separate security and operational review.
Done means
- You can show the effective
error/unixandretry/unixdefinitions withpostconf -M. - You can explain why the
errorservice bounces while theretryservice defers. - You recorded a recovery copy before changing
master.cf. - You verified the effective configuration after editing and reloaded Postfix only when it matched your plan.
- You checked the relevant queue ID and logs without manually deleting queued mail.