Home / Alt manpages / doveadm-fetch(1)

  • doveadm-fetch(1)
  • User command
  • linux

Read Dovecot Mail Without a Client Using doveadm fetch

You want to see what is actually in a Dovecot mailbox without opening a mail client, and doveadm fetch will print it. Allow about 15 minutes for a first check, plus time to identify the right mailbox and UIDs.

You will retrieve selected message metadata or content, using a search query narrow enough to review safely. This guide follows the Dovecot 2.3 command installed here: package dovecot-core version 1:2.3.21+dfsg1-2ubuntu6.5. Dovecot 2.4 has changed some doveadm defaults and requirements, so do not carry those assumptions over to this command.

1. Check the installed command

Run this as your normal account first. Fetch reads mail, and the command can expose complete messages, so treat the account and terminal with the same care as the mailbox itself. You may need an administrator account or sudo for your deployment's Dovecot socket permissions, but the syntax does not require elevated privileges:

$ command -v doveadm
/usr/bin/doveadm
$ dpkg-query -W -f='${Package} ${Version}\n' dovecot-core
dovecot-core 1:2.3.21+dfsg1-2ubuntu6.5
$ doveadm help fetch
DOVEADM-FETCH(1)                    Dovecot                   DOVEADM-FETCH(1)

The help command prints the installed manual. If command -v finds nothing, stop and install or enable Dovecot through your normal system-management process. Another host's output is no proof that this host has the same options.

2. Understand the command shape

The basic form is doveadm fetch [options] fields search_query. The fields say what to print, and the search query says which messages to select. With no user-selection option, this Dovecot 2.3 manual says the command uses the environment of the currently logged-in user. For an administrative check, make the target explicit with -u:

$ doveadm fetch -u '[email protected]' 'mailbox date.sent' \
  mailbox 'INBOX' subject 'SEARCH_TERM'

Replace every uppercase placeholder. The quoted field list is one argument containing two fields. The search query is made of terms such as mailbox, subject and uid plus their values, and its full grammar is in doveadm-search-query(7). If the query matches no messages, there may be no output.

Checkpoint

Confirm the intended user, mailbox and search terms before adding body or text. A metadata-only query is the safer first test.

3. Fetch a small metadata set

Use stable identifiers when you already know them. This example asks for the mailbox and sent date of three message UIDs in one mailbox:

$ doveadm fetch -u '[email protected]' 'mailbox date.sent' \
  mailbox-guid 'MAILBOX_GUID' uid '8,25,45'
mailbox: dovecot/pigeonhole/2.0
date.sent: 2010-01-19 01:17:41 (+0100)
^L
mailbox: dovecot/pigeonhole/2.0
date.sent: 2010-01-28 09:38:49 (+0100)

The exact mailbox name, dates and number of records depend on your data. The default formatter is pager: each field appears as key: value, and form-feed characters separate records. If you see ^L in a terminal or log, that is a record separator, not part of a mailbox value. Pick another formatter if you prefer:

  • -f flow gives key=value lines.
  • -f tab gives tab-separated output.
  • -f table gives an aligned table.
$ doveadm -f table fetch -u '[email protected]' 'uid size.virtual flags' \
  mailbox 'INBOX' all

Check the output before widening the query. For scripts, choose a formatter deliberately and allow for records that contain message text or unusual characters.

4. Fetch a header or body only when needed

The field decides how much data leaves the mailbox:

  • hdr returns the message header.
  • body returns the body.
  • text returns the complete message.
  • text.utf8 returns the complete message as UTF-8.

Other useful metadata fields include flags, guid, uid, size.physical, size.virtual, mailbox and user.

$ doveadm fetch -u '[email protected]' hdr \
  mailbox 'INBOX' uid 'MESSAGE_UID'
$ doveadm fetch -u '[email protected]' body \
  mailbox 'INBOX' uid 'MESSAGE_UID' > message-body.txt
$ test -s message-body.txt && echo 'body saved'
body saved

Warning

The redirection writes local data and can overwrite an existing file. Use a new filename or a guarded temporary path when the result matters:

$ output_file="message-body.$$.txt"
$ doveadm fetch -u '[email protected]' body \
  mailbox 'INBOX' uid 'MESSAGE_UID' > "$output_file" && \
  printf 'saved %s\n' "$output_file"
saved message-body.12345.txt

If the fetch fails, inspect the exit status and remove only the known incomplete output after checking its path. The original message is not altered by fetch. Do not put message contents in a shared terminal capture, ticket or debug log unless the recipient is authorised to see them.

5. Limit administrative scope

These options widen the reach of the command:

  • -u USER selects one user and accepts * and ? wildcards.
  • -F FILE reads one username per line and runs the command for every listed user.
  • -A runs it for all users.

These are read operations, but they can disclose a lot of personal data and create heavy mailbox or database load:

$ doveadm fetch -u '[email protected]' 'mailbox uid size.virtual' \
  mailbox 'INBOX' all
$ printf '%s\n' '[email protected]' > users-to-check.txt
$ doveadm fetch -F users-to-check.txt 'mailbox uid' mailbox 'INBOX' all

Warning

Do not use -A as a discovery shortcut. The 2.3 manual warns that combining it with a passwd userdb can include system users below first_valid_uid. For SQL or LDAP userdbs, iteration settings must match the database or directory schema. Start with one user and one narrow query, then get approval before widening the scope.

Checkpoint

If you created users-to-check.txt, review it and delete it when the operation is complete. It contains account names and may itself be sensitive. Nothing in these examples changes mailbox state, so there is no Dovecot undo to worry about.

6. Diagnose an empty or failed result

An empty result normally means no message matched the query. It does not mean fetch silently fetched everything. Recheck the exact mailbox spelling, user, UID and search terms. Search terms are not shell globs unless the search-query syntax defines them as such.

For more detail, add the global -v option for verbosity and progress, or -D for debug messages:

$ doveadm -v fetch -u '[email protected]' 'uid mailbox' \
  mailbox 'INBOX' uid 'MESSAGE_UID'
  • Socket or permission error. This is an access or deployment problem. -S can select an absolute UNIX socket path or a HOST:PORT TCP endpoint, but use it only when your Dovecot configuration documents that endpoint. A remote socket can send mailbox data across the network, so check transport and authorisation first.
  • Unknown field. Compare it with the installed manual.
  • Malformed query. Reduce it to mailbox INBOX uid MESSAGE_UID, verify that form, then add one condition at a time.

Tip

Avoid repeatedly retrying a broad query against a busy production service.

Done means

  • Command confirmed. You checked the installed Dovecot package and the local doveadm fetch syntax.
  • Scope narrow. You selected one explicit user, mailbox and search query before reading message content.
  • Output fitted. You chose fields and a formatter that match the amount and shape of data required.
  • Content treated as sensitive. hdr, body, text and text.utf8 output is handled with care.
  • Wide options understood. You know that -A and -F expand scope and may need careful userdb configuration.
  • Mailbox untouched. The original mailbox is unchanged and any local output file was handled deliberately.