PowerMTA Config File Structure Explained: Complete 2026 Operator Guide

← PowerMTA Operations

PowerMTA Config File Structure Explained: Complete 2026 Operator Guide to the Configuration File

December 10, 2027·10 min read·Sigrid Andersen

Why understanding the config file matters

Almost everything an operator does with PowerMTA, configuring virtual MTAs, tuning domain throttling, setting up DKIM, defining accounting, comes down to editing the configuration file. An operator who understands the file's structure, the syntax, the block types, the inheritance, reads and edits it confidently; an operator who does not is making changes to a file whose logic they do not fully grasp, which is how configuration mistakes happen.

This guide exists to explain the PowerMTA configuration file structure clearly, as a foundation for all the more specific configuration tasks. The structure of this guide: why understanding the config file matters, the main configuration file and its location, the directive-and-block syntax PowerMTA uses, the major block types, the distinction between global directives and block-scoped directives, how directive inheritance and the domain default block work, including additional files and writing comments, and the validate-then-reload workflow for applying configuration changes safely.

The main configuration file

PowerMTA's configuration is held in a single main configuration file. On a Linux installation, that file is conventionally at:

/etc/pmta/config

PowerMTA reads this file when it starts and when it is reloaded. The file contains the deployment's complete configuration: the global settings, the virtual MTAs, the domain blocks, the accounting setup, everything that defines how PowerMTA behaves.

The single-file model is the default and the simplest arrangement, the whole configuration in one file. For larger or more complex deployments, the configuration can be split across multiple files for organization, using the include directive covered later, but even then there is one main file that is the entry point.

So for an operator working with a PowerMTA deployment, the starting point is always the main config file at /etc/pmta/config. From there, any include directives show where the rest of the configuration lives. The location can differ on non-default installations, but /etc/pmta/config is the standard Linux location and the first place to look.

The directive-and-block syntax

The PowerMTA configuration file uses a syntax built from two elements: directives and blocks.

A directive is a single configuration setting. It is written as a keyword followed by its value or values, on one line:

max-message-rate 10000/h
log-file /var/log/pmta/log

A block is a named, bracketed grouping of directives that applies to a particular entity. A block is opened with a tag in angle brackets naming the block type and an identifier, and closed with a matching closing tag, and the directives written inside apply to that block's entity:

<virtual-mta mta-ip-1>
    smtp-source-host 203.0.113.10 mail1.example.com
</virtual-mta>

So the configuration is essentially a collection of global directives, written at the top level, and blocks, each containing the directives scoped to a particular entity. The syntax is plain text, line-oriented, and reasonably readable: an operator looking at a config file sees the global directives and then the series of blocks, each delimited by its opening and closing tags, with the directives inside.

Blocks can also be nested in some cases, a block containing another block, where the inner block is scoped within the outer. Understanding this directive-and-block structure is the foundation for reading and editing a PowerMTA configuration, because every part of the configuration is either a directive or a block of directives.

The major block types

The block types are identified by their tag. The major block types an operator encounters:

Block typeWhat it configures
virtual-mtaA virtual MTA: a sending IP and its identity
virtual-mta-poolA pool grouping several virtual MTAs
domainThe handling for a destination domain
smtp-pattern-listA list of patterns for matching SMTP responses
bounce-category-patternsPatterns for categorizing bounces
acct-fileAn accounting log file definition
sourceA source of mail submission and its permissions

The virtual-mta block defines a virtual MTA, a sending IP and the identity, HELO and DKIM, that goes with it. The virtual-mta-pool block groups several VMTAs into a pool for distribution.

The domain block defines the handling for a destination domain, the throttling, the connection limits, the routing. Domain blocks are among the most-edited parts of the configuration.

The smtp-pattern-list and bounce-category-patterns blocks define patterns, for matching SMTP responses and for categorizing bounces respectively.

The acct-file block defines an accounting log file, what records it captures and where it is written. The source block defines a source of mail submission and what it is permitted to do.

This is not the complete list of block types, but it covers the ones an operator works with most. Each block type has its own set of valid directives, the directives meaningful inside a domain block differ from those inside a virtual-mta block, and the PowerMTA documentation is the reference for which directives belong in which block.

Global directives versus block-scoped directives

An important distinction in reading the configuration is between global directives and block-scoped directives.

Global directives are written at the top level of the configuration, not inside any block. They apply to PowerMTA overall. Things like the main log file location, certain server-wide settings, and global defaults are global directives.

Block-scoped directives are written inside a block, and they apply to that block's entity. The smtp-source-host directive inside a virtual-mta block applies to that VMTA; a max-msg-rate directive inside a domain block applies to that domain.

The same directive keyword can sometimes be valid both globally and within a block, with the global instance setting a default and the block instance setting the value for that block, which is the basis of the inheritance covered next. But many directives are specific to one context: a directive that configures a VMTA's source IP only makes sense inside a virtual-mta block.

For an operator reading the configuration, the position of a directive, top-level or inside a block, tells them its scope. A directive at the top level affects PowerMTA broadly; a directive inside a block affects only that block's entity. And when editing, placing a directive in the wrong scope, putting a block-specific directive at the top level or vice versa, is a configuration error the validation will typically catch.

Inheritance and the domain default block

PowerMTA's configuration has an inheritance model, where a directive set at a broader scope provides a default that a narrower scope can override. The clearest and most important example is the domain configuration and the domain default block.

PowerMTA supports a domain default block, a domain block whose identifier marks it as the default:

<domain default>
    max-msg-rate 5000/h
    max-smtp-out 10
    bounce-after 4d12h
</domain>

The directives in the domain default block apply to every destination domain that does not have its own specific domain block. So an operator sets sensible throttling and behavior in the default block, and every receiver without a dedicated block inherits those settings.

When a specific domain does have its own block, that block's directives apply to that domain and override the default for it:

<domain gmail.com>
    max-msg-rate 15000/h
</domain>

Here, gmail.com gets a max-msg-rate of 15000/h, overriding the default's 5000/h. But notice the gmail.com block sets only max-msg-rate; for the directives it does not set, max-smtp-out, bounce-after, gmail.com still inherits from the default. A specific domain block does not have to restate every setting; it carries only the directives that differ.

A domain's effective configuration is the default plus its own block

When reading a PowerMTA configuration, an operator must remember that a specific domain's effective configuration is not just what is written in that domain's own block, it is the combination of the domain default block and the domain's own block, with the domain's own block winning where the two overlap. Looking at a domain block in isolation and concluding that is the domain's full configuration is a mistake: the directives the domain block does not set are inherited from the default. To know how PowerMTA actually handles a domain, the operator must consider both the default block and the domain's specific block together. The pmta show settings command, which displays the effective configuration, is the reliable way to see the result of the inheritance rather than inferring it.

This inheritance makes the configuration compact and maintainable: the common behavior goes in the default, each specific domain block carries only its differences, and a change to the common behavior is made once in the default rather than in every domain block.

Including additional files and comments

Two organizational features of the configuration file deserve mention: includes and comments.

The include directive. For a large or complex configuration, keeping everything in one file becomes unwieldy. PowerMTA supports an include directive that pulls in additional files:

# In the main config file
include /etc/pmta/vmtas.conf
include /etc/pmta/domains.conf

With includes, the main config file becomes a top-level file that includes separate files for, say, the virtual MTAs, the domain blocks, the patterns. The included files are still part of the one logical configuration; the include mechanism is purely an organizational convenience. A deployment with many VMTAs and many domain blocks is often easier to maintain with the configuration split into focused files. The included files follow the same directive-and-block syntax.

Comments. The configuration file supports comments, lines or portions of lines marked as comments that PowerMTA ignores, conventionally with a leading hash:

# This is a comment explaining the block below
<domain gmail.com>
    max-msg-rate 15000/h   # raised after warming completed
</domain>

Comments are valuable in a configuration file. A well-commented config explains why a particular setting is what it is, when it was changed, what a block is for, which is genuinely useful when the operator, or a colleague, returns to the configuration later. An uncommented config of any size forces the reader to infer the intent behind every setting. Using comments to document the configuration is a good practice, especially for any non-obvious setting.

The validate-then-reload workflow

Editing the configuration file is only useful if the changes are applied correctly, and PowerMTA provides a workflow that makes applying changes safe: validate, then reload.

The workflow:

  1. Back up the configuration. Before editing, copy the current configuration file. If a change goes wrong, the backup is the fast way back.
  2. Edit the configuration. Make the change in the config file.
  3. Validate the configuration. Run PowerMTA's configuration check. The command verifies the configuration file is syntactically valid, the blocks are well-formed, the directives are recognized and in valid scopes, before the configuration is applied.
  4. # Validate the configuration without applying it
    pmta verify config
  5. Reload only after validation passes. If the validation reports the configuration is valid, apply it with a reload. The reload makes PowerMTA re-read the configuration and apply the changes.
  6. # Apply the validated configuration
    pmta reload
  7. Confirm the result. After reloading, confirm the change took effect, with pmta show settings to see the effective configuration, and watch that PowerMTA is operating normally.

The critical discipline is to validate before reloading. The validation step catches syntax errors, malformed blocks, misplaced directives, before they are applied. Reloading a broken configuration without validating first risks PowerMTA failing to apply the configuration or, worse, a disruption to the running service. The validate-then-reload sequence ensures a configuration error is caught as a validation message, which is harmless, rather than as a service problem, which is not.

The reload itself is a graceful operation, PowerMTA re-reads the configuration and applies the changes without a full restart, so a normal configuration change does not interrupt sending. The combination, back up, edit, validate, reload, confirm, is the safe workflow for every configuration change, and following it consistently is what keeps configuration changes from becoming incidents.

The config change that a skipped validation turned into an outage

An operator we worked with needed to make a quick configuration change to PowerMTA, an adjustment to a domain block's throttling. It was a small change, a single directive, and they were confident in it, so they made the edit directly in the main config file and immediately ran pmta reload to apply it. They skipped the validation step, reasoning that a one-line change to a familiar directive did not need checking. The reload did not go as expected. PowerMTA failed to apply the new configuration, and because of how they had edited the file, the deployment was left in a bad state, sending was disrupted. When they investigated, the cause was a small syntax error in their edit: in making the one-line change, they had accidentally deleted the closing angle bracket of the domain block's closing tag, turning a valid block into a malformed one. It was a trivial typo, the kind that is easy to make and easy to miss when editing quickly. But a malformed block makes the whole configuration invalid, and PowerMTA could not load it. Had they run pmta verify config before reloading, the validation would have reported the malformed block immediately, as a harmless error message, and they would have fixed the typo and reloaded a valid configuration with no disruption at all. Instead, by reloading an unvalidated configuration, they had turned a one-character typo into a sending outage. The recovery was to fix the typo, validate the corrected configuration, confirm it was now valid, and reload, after which sending resumed, but the deployment had been disrupted for the duration. They had also, fortunately, made a backup before editing, which meant that even if the fix had not been obvious, they had a known-good configuration to restore. The lesson is the validate-then-reload discipline. The validation step exists precisely to catch the syntax errors, the malformed blocks, the misplaced directives, that are easy to introduce when editing a configuration file, especially when editing quickly and confidently. A one-line change feels too small to need validation, but a one-character typo in that one line is exactly what validation catches and exactly what, unvalidated, turns into an outage. Every configuration change, however small, goes through back up, edit, validate, and only then reload, because the cost of validation is a few seconds and the cost of skipping it can be a disruption to the running service.

The PowerMTA configuration file is the single place an operator defines how PowerMTA behaves, and understanding its structure is the foundation for every configuration task. The configuration lives in a main file, conventionally /etc/pmta/config, and is written in a directive-and-block syntax: directives are single settings, blocks are bracketed groupings of directives scoped to an entity like a virtual MTA or a domain. The major block types, virtual-mta, domain, the pattern lists, acct-file, source, and others, each configure a kind of entity. Directives are either global, at the top level affecting PowerMTA overall, or block-scoped, affecting their block's entity. The inheritance model, most importantly the domain default block, means a domain's effective configuration is the default plus its own block, so a domain block must never be read in isolation. The include directive splits a large configuration across files for organization, and comments document the intent behind settings. And every change, however small, follows the validate-then-reload workflow, back up, edit, run pmta verify config, and only reload once validation passes, because the validation step catches the syntax errors that, unvalidated, turn into outages. Operators who understand the structure and follow the safe workflow edit PowerMTA's configuration with confidence; operators who edit a file whose logic they do not grasp, or skip validation, find configuration changes becoming incidents.

S
Sigrid Andersen

Email Systems Architect at Cloud Server for Email. Designs and maintains PowerMTA configurations for ESP clients. Related: Virtual MTA Configuration with Multiple IPs, Domain Block Configuration and Throttling, Configuration Backup and Disaster Recovery.