Knowledge base

PMTA knowledge base›Block <domain>›Directive§ 3.3.10.110.2

file-destination

<domain>

Where the queue writes files — a directory or a file name
in the configuration this is a linefile-destinationinside the block <domain>
A path into which message properties can be substituted

It works for a file queue (type). It sets a directory — if file-format creates a file per message — or a file name, if messages are appended to a shared one.

The path does not have to be constant. The same substitutions are expanded in it as in the handler program’s command line: $isodate — a date like 2026-08-28, $domain — the recipient domain, $user — the recipient name before the at sign (and if it contains +, the part to the left of it), $from and $to — the envelope addresses, $envid, $timet, $ctime, $rfctime, $bodytype.

The case of the expansion differs. $user and $domain are always lowercased — so as not to produce two directories for the same name in different cases. $from and $to depend on macro-variables-preserve-case.

The main trap is a path without substitutions. A directory into which everything is dumped accumulates hundreds of thousands of files in a week, and operations on it start to cost more than the delivery itself. Split it at least by date: $isodate in the path is one line, and it makes the difference between a directory per day and a directory per year.
What the Hub does. It does not write it: it creates no file queues. If such a queue is ever needed, the path is worth building with $isodate — otherwise investigating the archive will run into the file system, not the message volume.
Recommended values

A date in the path is the minimum. $isodate splits the archive by day and makes it suitable for deletion by age.

$domain is more useful than $to. A directory name from the recipient domain is readable and does not produce a directory per address.

The directory must exist in advance. Substitutions expand into the path, but the node does not create directories for you — unlike the bundled newfile program, which can.

The advice about date substitution and the warning about a pre-created directory are ours. From the manual here come the full list of substitutions and the case rule: the recipient name and its domain are always lowercase.
Example configuration
# the archive is split by day and by domain
<domain archive.example.com>
    type file
    file-format newfile-pickup
    file-destination /var/spool/archive/$isodate/$domain/</domain>
Both substitutions expand in lowercase — $domain always, regardless of how the domain is written in the address.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
▲

Common mistakes and problems

what people get wrong and how it ends2 mistakes▶

Writing everything into one directory

our experience

What it costsIn a week it holds hundreds of thousands of files, and any operation on the directory — listing, deletion by age — starts to cost more than the delivery itself.
How to spot itArchive processing slows down, although the message volume is not growing.
How to do it rightAdd $isodate to the path — a directory per day.

Expecting the directory to be created automatically

§ 3.3.10.110.2

What it costsSubstitutions expand into the path, but the node does not create directories. Messages stay in the queue, and the cause is visible only from permissions and whether the directory exists.
How to spot itThe file queue grows, and there are no files on disk.
How to do it rightCreate the directories in advance — or switch to a pipe queue with the bundled newfile program, which creates them itself.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
Reference data
Syntax
file-destination <path>
Values
a path to a directory or a file; the substitutions $isodate, $domain, $user, $from, $to, $envid, $timet, $ctime, $rfctime, $bodytype are allowed
Applying
reload, no restart needed
Queue
will not touch what is already queued
Where to write it
<domain>
How many times
once in the block
Everything here comes from the manual, with the section.
Inheritance
The value merges across <domain> blocks from general to specific: the best-matching block wins, not the last one in the file. In a queue of another type the line is ignored. It is picked up by pmta reload; messages already in the queue will go to the new path.
How to check on the node
The value is printed by the queue settings command; whether the path expanded as intended is visible from the directory itself:
pmta show settings archive.example.com/vmta1 | grep -i file-destination
find /var/spool/archive/ -name '*.msg' -newermt '-1 hour' | head
An empty response from the second command with a non-empty queue usually means the directory from the substitution does not exist: the node does not create it. The Hub does not create file queues.
In the Hub
Cost of a mistake
dangerous: effects outlast a rollback
Scenarios
Connect a sending platform