Knowledge base

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

macro-variables-preserve-case

<domain>

Whether to preserve address case in substitutions
in the configuration this is a linemacro-variables-preserve-case falseinside the block <domain>
Address case on the command line and in the path

The substitutions the node expands in the command line and in the file-destination path are lowercased by default. This line cancels the lowercasing — but only for two of them.

$to and $from — yes, their case can be preserved. These are the full envelope addresses, and in rare cases the receiving side is case-sensitive.

$user and $domain — no, they are always lowercased. The manual explains why: they are used to make directory and file names, and on case-sensitive file systems Example.com and example.com are two different directories.

The main trap is enabling it and expecting the wrong thing. The line does not affect $user and $domain, and it is exactly those that most often appear in the path. Enabling looks like “now case is preserved everywhere”, while it is preserved in exactly two substitutions out of ten.
What the Hub does. It does not write it: it does not create queues of the pipe and file types. If such a queue appears, the default is the right value: lowercasing saves you from two directories for one name.
Recommended values

The default is almost always right. Lowercase is what both the file system and address comparison need.

Enable it only for a specific requirement. A handler that needs the original case of the envelope address is rare, and it is usually better to teach it to compare case-insensitively.

It will not affect directory names. $user and $domain are lowercased with any value.

The advice to teach the handler to compare case-insensitively is ours. From the manual come the default and the exact list: the line concerns full envelope addresses, while the recipient’s user name and domain are always lowercased.
Example configuration
# the handler needs the original case of the envelope address
<domain bounces.example.com>
    type pipe
    command "/opt/bounce/parse --to \"$to\" \"$user\""
    macro-variables-preserve-case true</domain>
The case will be preserved for $to, but not for $user in the same line — it is lowercased with any value.
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▶

Enabling it for the sake of directory names

§ 3.3.10.111.2

What it costs$user and $domain are lowercased with any value. Directories keep their lowercase names, while the setting looks applied.
How to spot itThe line is on, directory names have not changed.
How to do it rightNothing: this is the engine’s behavior. Case is preserved only for $to and $from.

Enabling it “just in case”

our experience

What it costsThe envelope address starts reaching the handler in its original case. Comparison with a database where addresses are stored in lowercase stops matching — and bounces get attributed to the wrong recipients.
How to spot itAfter enabling, the handler stopped finding some of the addresses.
How to do it rightReturn the default or teach the handler to compare case-insensitively.
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
macro-variables-preserve-case <boolean>
Values
yes or no; true and false are accepted on a par with them
Default
false § 3.3.10.111.2
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 is merged 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 comes from the pipe section, although the same substitutions are expanded in the path of a file type queue too. It is picked up by pmta reload.
How to check on the node
The value is printed by the queue settings command; the result is visible from what the handler receives:
pmta show settings bounces.example.com/vmta1 | grep -i macro-variables
There is no way to check substitution expansion on a live node — all that remains is to look at what the handler received as input. The Hub does not create pipe type queues.
In the Hub
Cost of a mistake
dangerous: effects outlast a rollback
Scenarios
Connect a sending platform