Inspect and Safely Trigger the Postfix Mail Queue with postqueue
You will finish with a repeatable way to inspect the Postfix mail queue, save a machine-readable listing, and request delivery for one message, one destination or the whole queue. The examples use Postfix 3.8.6-1ubuntu0.1, installed here as the postfix package. Allow about ten minutes if Postfix is already running.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell account allowed to view the queue. Viewing and most delivery requests are normally ordinary user commands, although Postfix authorisation and the local service configuration still apply. The command has set-group-ID privileges so it can contact Postfix daemons. You do not need sudo merely because the command is an administrative tool.
1. Confirm the installed command
Check which executable will run and read its local manual page before using a flag copied from another Postfix release:
$ command -v postqueue
/usr/sbin/postqueue
$ dpkg-query -W -f='${Package} ${Version}\n' postfix
postfix 3.8.6-1ubuntu0.1
$ postqueue 2>&1 | head -2
postqueue: fatal: usage: postqueue -f | postqueue -i queueid | postqueue -j | postqueue -p | postqueue -s site
The exact help wording can vary. The useful checks are that the command resolves to the expected Postfix installation and that the package version is known. This guide describes the installed 3.8.6 behaviour; the local manual page is the authority if a different machine reports another version.
2. Read the traditional queue listing
Start with -p, which produces the familiar sendmail-style listing:
$ postqueue -p
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
72D6CD1C0583 5222 Sat Sep 26 09:14:27 MAILER-DAEMON
www-data@1e1e40a960ad
-- 5 Kbytes in 1 Request.
Your queue will differ, and an empty queue normally ends with a message saying it is empty. Each entry contains a queue ID, message size, arrival time, envelope sender and recipients still awaiting delivery. A reason for a previous delivery failure may appear below the recipient.
Do not interpret a queue listing as a complete, frozen snapshot. The showq daemon can list mail while delivery continues, so a message may disappear, move or be reported more than once as the queue changes. Re-run the command when checking a result.
Checkpoint
Copy a queue ID only from the current listing. Queue IDs can be reused within a Postfix instance, and they are not globally unique across separate instances.
3. Produce JSON Lines for scripts
Use -j when another program needs to process the listing. It emits one JSON object per queue file, one object per line:
$ postqueue -j
{"queue_name":"deferred","queue_id":"72D6CD1C0583","arrival_time":1790254867,"message_size":5222,"forced_expire":false,"sender":"MAILER-DAEMON","recipients":[{"address":"www-data@1e1e40a960ad","delay_reason":"Host or domain name not found. Name service error"}]}
In this format, arrival_time is seconds since the Unix epoch, message_size counts the message header and body but not envelope data, and recipients is an array. A recipient can have a delay_reason, but it can be absent while delivery is in progress or after an abrupt stop.
The JSON format is available from Postfix 3.1 onwards. Keep parsers tolerant: the manual says that additional object members may be added. For a quick count on a machine with jq installed:
$ postqueue -j | jq -s 'length'
1
The command writes diagnostics to standard error and the listing to standard output. If you redirect the output, keep errors separate so a failure message cannot be mistaken for JSON:
$ postqueue -j > queue.jsonl
$ jq -e 'select(.queue_id)' queue.jsonl > /dev/null
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
4. Request delivery for one queue ID
After checking the current listing, request immediate delivery of deferred mail for one queue ID with -i:
$ postqueue -i 72D6CD1C0583
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
This contacts the Postfix flush service. It schedules delivery; it does not guarantee that the message will be delivered, and it does not repair DNS, authentication, routing or recipient problems. Check the queue again and inspect the Postfix logs using the logging system configured on your machine.
This operation changes delivery scheduling but does not edit the message contents. There is no separate undo command. If you triggered it accidentally, let the normal delivery process finish or correct the underlying delivery problem. Do not repeatedly flush an undeliverable message: the manual warns that frequent flushing can reduce delivery performance for other mail.
5. Target a destination or flush the whole queue
Use -s with a site when you have a specific destination to retry:
$ postqueue -s example.net
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
A numeric destination must be written as an RFC 5321 address literal, including square brackets, such as [192.0.2.10]. The destination must also be eligible for Postfix fast flush service. A normal domain name is usually the clearer choice when it is configured for that service.
Use -f only when you deliberately want Postfix to attempt delivery for all queued mail:
$ postqueue -f
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
Warning
This can generate substantial delivery activity. It is not a diagnostic command and it is not a way to delete or permanently force mail through. Resolve the cause of a queue backlog first, then use a targeted request where possible.
6. Use a non-default configuration carefully
Pass -c when the Postfix main.cf file is in a different configuration directory:
$ postqueue -c /etc/postfix-test -j
{"queue_name":"deferred","queue_id":"...","arrival_time":1790254867,"message_size":5222,"forced_expire":false,"sender":"...","recipients":[]}
Replace the path with a real directory containing the intended main.cf. A non-standard directory is permitted for an ordinary user only when the standard configuration lists it in alternate_config_directories; the super-user is subject to a different restriction. Do not set MAIL_CONFIG or use -c to point at an untrusted directory in an attempt to bypass that check.
If you need verbose diagnostics, add -v. On Postfix 2.3 and later, the manual restricts this option to the super-user. Multiple -v options increase verbosity. Capture verbose output only when needed because it can expose operational details in logs or terminal history.
7. Keep destructive queue work separate
postqueue does not delete queued messages or change their hold status. Those are privileged queue operations provided by postsuper. Treat commands that remove or expire mail as a separate change: identify the exact queue ID, confirm the sender and recipients, check the retention requirement, and make a recovery plan before running them. A delivery request made with this guide is reversible only by allowing the normal queue process to continue; deletion is not.
Done means
- You confirmed the installed Postfix version and executable.
- You can inspect the queue with
postqueue -pand script againstpostqueue -j. - You use a current queue ID for a targeted
-irequest, or a configured site for-s. - You reserve
-ffor deliberate, service-aware recovery and do not repeat it blindly. - You understand that
postqueueschedules delivery but does not delete mail or guarantee delivery.