Home / Alt manpages / postcat(1)

  • postcat(1)
  • User command
  • linux

Inspect Postfix Queue Files Safely with postcat

You will finish with a repeatable way to read a Postfix queue file without sending, deleting or re-queuing the message. You will be able to inspect the envelope, headers and body separately, find a queue file by ID, and recognise the difference between a bad path and a malformed file.

Allow about fifteen minutes. You need shell access to a Postfix host and the postcat command from the Postfix package. The examples were checked against Postfix 3.8.6-1ubuntu0.1. Reading a queue file may expose message content and recipient addresses, so treat the output as sensitive. Use an account that can read the file, and do not paste the result into an issue or chat without checking for personal data.

1. Check the installed command and queue location

Start with read-only checks. These do not need elevated privileges unless your local package metadata or configuration is restricted:

$ command -v postcat
/usr/sbin/postcat
$ dpkg-query -W -f='${Package} ${Version}\n' postfix
postfix 3.8.6-1ubuntu0.1
$ postconf queue_directory config_directory
queue_directory = /var/spool/postfix
config_directory = /etc/postfix

Your binary path and package version may differ. postcat does not provide a portable --version option, so use the package manager to identify the installed version. The command reads the Postfix configuration to determine defaults. MAIL_CONFIG or -c can change which configuration directory is used.

Checkpoint: you know which Postfix installation you are inspecting and where its queue is configured. Do not assume that /var/spool/postfix is correct on a host with a non-default queue_directory.

2. Identify a queue file without changing it

A queue file name is normally a queue ID, such as 3F2A812345. First list candidate files under the configured queue directory. This is ordinary read-only work, but the directory may require an administrator or the Postfix group to read it:

$ find /var/spool/postfix -type f -name '3F2A812345' -print
/var/spool/postfix/deferred/3/3F2A812345

Replace both occurrences of 3F2A812345 with the actual queue ID. Queue files are distributed among queue subdirectories, so looking only in incoming or deferred can miss a file. If you already have the exact path, pass that path directly and omit -q.

Postfix may move or remove queue files while mail is being delivered or managed. If a path vanishes between find and postcat, repeat the lookup. Do not copy a queue file into another directory and then treat the copy as a live queue item: it is only a diagnostic snapshot.

3. Read the complete queue record

With an exact path, run postcat as the account that can read it:

$ postcat /var/spool/postfix/deferred/3/3F2A812345

By default, Postfix shows the envelope and message content, equivalent to requesting -b -e -h. The output is human-readable, not a format to edit and write back. It can include sender and recipient information, message headers, and the body.

Checkpoint: confirm that the displayed queue ID and message details are the item you intended to investigate. Stop if the output contains a different message or sensitive data that you did not expect.

4. Narrow the output when you need one part

Use the explicit selectors when a full dump is distracting:

$ postcat -e /var/spool/postfix/deferred/3/3F2A812345
$ postcat -h /var/spool/postfix/deferred/3/3F2A812345
$ postcat -b /var/spool/postfix/deferred/3/3F2A812345
$ postcat -bh /var/spool/postfix/deferred/3/3F2A812345

-e shows envelope records. -h shows message headers, from the start of the message up to the first non-header line. -b shows the message body from the first non-header line to the end of the message. The combined -bh form is useful when you need message content but not the envelope. These selectors are available in Postfix 2.7 and later, including the installed version.

Do not infer delivery status from an empty body or header section. A message can have an unusual or empty part while the queue record remains valid. If you need to understand record boundaries, add -d for decimal record types and -o for queue-file offsets:

$ postcat -do /var/spool/postfix/deferred/3/3F2A812345

The extra metadata is for diagnosis. It is not a repair mode.

5. Search the queue by ID when the path is unknown

Use -q when you have a queue-file name but not its current subdirectory:

$ postcat -q 3F2A812345

This asks Postfix to search its queue for the named file instead of interpreting the argument as a literal path. It was added in Postfix 2.0 and later. If the ID is not present, check whether the message has already been delivered, expired, moved, or removed by queue management. A missing file is not a reason to create one by hand.

For a different configuration directory, supply it explicitly:

$ postcat -c /etc/postfix-example -q 3F2A812345

Use -c only when you have verified that the directory contains the configuration for the queue you mean to inspect. Pointing at a different Postfix instance can produce a confusing "not found" result.

6. Handle permissions and malformed records

If you receive a permission error, first confirm the path and permissions without changing them:

$ ls -l /var/spool/postfix/deferred/3/3F2A812345
$ test -r /var/spool/postfix/deferred/3/3F2A812345 && echo readable

Only use an elevated shell if your normal operational procedure permits it and the message content is authorised for you to view. sudo postcat ... reads potentially confidential mail; it does not make the data less sensitive. Do not alter ownership or permissions merely to make an investigation convenient.

A malformed or truncated file causes diagnostics on standard error and a non-zero exit status. For example, feeding arbitrary text through standard input produces an error like this:

$ printf 'not-a-queue-file\n' | postcat
postcat: warning: stdin: unexpected EOF in data, record type 110 length 111
postcat: fatal: record read error
$ printf 'exit status: %s\n' "$?"
exit status: 1

The record type and length are data-dependent, so do not script against those numbers. Save standard error separately when you need an audit trail, but remember that the normal output may contain message content.

7. Use advanced diagnostics only when needed

Postfix 3.7 and later provide -r to print records in file order without following pointer records, and -s to skip to a specified queue-file offset. These options are useful when investigating pointer layout or a known offset, but they are easy to misuse. Establish the relevant offset with -o first, and keep the original queue file untouched.

Use -v for verbose logging, adding it again for progressively more detail. Verbose messages go to standard error. They diagnose the read; they do not validate a message for delivery, repair a queue file, or change Postfix behaviour.

Done means

  • You identified the installed Postfix version and the configured queue directory.
  • You inspected an existing queue file with postcat and changed no queue state.
  • You can select envelope, headers, body, record types, or offsets for a focused read.
  • You know when -q and -c are appropriate, and when an exact path is safer.
  • You checked permissions and treated message output as sensitive data.
  • You can distinguish a missing queue file from a malformed queue record by its diagnostic and exit status.