maddy is built of many small components called "modules". Each module does one certain well-defined task. Modules can be connected to each other in arbitrary ways to achieve wanted functionality. Default configuration file defines set of modules that together implement typical email server stack.

To specify the module that should be used by another module for something, look for configuration directives with "module reference" argument. Then put the module name as an argument for it. Optionally, if referenced module needs that, put additional arguments after the name. You can also put a configuration block with additional directives specifing the module configuration.

Here are some examples:

smtp ... {
    # Deliver messages to the 'dummy' module with the default configuration.
    deliver_to dummy

    # Deliver messages to the 'target.smtp' module with
    # 'tcp://' argument as a configuration.
    deliver_to smtp tcp://

    # Deliver messages to the 'queue' module with the specified configuration.
    deliver_to queue {
        target ...
        max_tries 10

Additionally, module configuration can be placed in a separate named block at the top-level and merely referenced by its name where it is needed.

Here is the example:

storage.imapsql local_mailboxes {
    driver sqlite3
    dsn all.db

smtp ... {
    deliver_to &local_mailboxes

It is recommended to use this syntax for modules that are 'expensive' to initialize such as storage backends and authentication providers.

For top-level configuration block definition, syntax is as follows:

namespace.module_name config_block_name... {

If config_block_name is omitted, it will be the same as module_name. Multiple names can be specified. All names must be unique.

Note the "storage." prefix. The actual module name is this and includes "namespace". It is a little cheating to make more concise names and can be omitted when you reference the module where it is used since it can be implied (e.g. putting module reference in "check{}" likely means you want something with "check." prefix)

Usual module arguments can't be specified when using this syntax, however, modules usually provide explicit directives that allow to specify the needed values. For example 'sql sqlite3 all.db' is equivalent to

storage.imapsql {
    driver sqlite3
    dsn all.db

Reference documentation conventions

Syntax descriptions for directives

Underlined values are placeholders and should be replaced by your values. boolean is either 'yes' or 'no' string.

Ellipsis (_smth..._) means that multiple values can be specified

Multiple values listed with '|' (pipe) separator mean that any of them can be used.

Global directives

These directives applied for all configuration blocks that don't override it.

Syntax: state_dir path
Default: /var/lib/maddy

The path to the state directory. This directory will be used to store all persistent data and should be writable.

Syntax: runtime_dir path
Default: /run/maddy

The path to the runtime directory. Used for Unix sockets and other temporary objects. Should be writable.

Syntax: hostname domain
Default: not specified

Internet hostname of this mail server. Typicall FQDN is used. It is recommended to make sure domain specified here resolved to the public IP of the server.

Syntax: autogenerated_msg_domain domain
Default: not specified

Domain that is used in From field for auto-generated messages (such as Delivery Status Notifications).

tls file cert_file pkey_file
tls module reference
tls off
Default: not specified

Default TLS certificate to use for all endpoints.

Must be present in either all endpoint modules configuration blocks or as global directive.

You can also specify other configuration options such as cipher suites and TLS version. See maddy-tls(5) for details. maddy uses reasonable cipher suites and TLS versions by default so you generally don't have to worry about it.

Syntax: tls_client { ... }
Default: not specified

This is optional block that specifies various TLS-related options to use when making outbound connections. See TLS client configuration for details on directives that can be used in it. maddy uses reasonable cipher suites and TLS versions by default so you generally don't have to worry about it.

log targets...
log off
Default: stderr

Write log to one of more "targets".

The target can be one or the following:


log syslog /var/log/maddy.log

Note: Maddy does not perform log files rotation, this is the job of the logrotate daemon. Send SIGUSR1 to maddy process to make it reopen log files.

Syntax: debug boolean
Default: no

Enable verbose logging for all modules. You don't need that unless you are reporting a bug.

Prometheus/OpenMetrics endpoint

openmetrics tcp:// { }

This will enable HTTP listener that will serve telemetry in OpenMetrics format. (It is compatible with Prometheus).

See documentation page the list of metrics exposed.



Stop the server process gracefully. Send the signal second time to force immediate shutdown (likely unclean).


Reopen log files, if any are used.


Reload some files from disk, including alias mappings and TLS certificates. This does not include the main configuration, though.


Maintained by Max Mazurov Project includes contributions made by other people.

Source code is available at

See also

maddy-config(5) - Detailed configuration syntax description
maddy-imap(5) - IMAP endpoint module reference
maddy-smtp(5) - SMTP & Submission endpoint module reference
maddy-targets(5) - Delivery targets reference
maddy-storage(5) - Storage modules reference
maddy-auth(5) - Authentication modules reference
maddy-filters(5) - Message filtering modules reference
maddy-tables(5) - Table modules reference
maddy-tls(5) - Advanced TLS client & server configuration