Knowledge base

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

smtp-tls-max-version

<domain>

The upper bound of the TLS version to the receiver
in the configuration this is a linesmtp-tls-max-version none, which behaves as tlsv1.3inside the block <domain>
Which version not to go above

The second bound of the range. The values are the same — tlsv1, tlsv1.1, tlsv1.2, tlsv1.3; there is no default, that is, the upper bound is unlimited and in practice equals tlsv1.3.

The line is rarely needed and almost always as a workaround for someone else’s bug. The normal case is to negotiate the newest version both sides understand; limiting from above makes sense when a receiver announces tlsv1.3 and breaks on it.

One known consequence of lowering the ceiling: reuse-ssl-session does not work on tlsv1.3. By lowering the ceiling to tlsv1.2, you enable session reuse — but that is not a reason to do it, just a side effect worth knowing about.

The main trap is treating with a ceiling what is treated with a floor. A limit from above looks harmless and silently keeps the connection on an old version forever: the receiver gets updated, but the configuration does not. The line is set for a specific reason and removed when the reason is gone.
What the Hub does. It does not write it: the upper bound is unlimited, and that is right — the node negotiates the newest version the receiver understands. The line will come in handy in a targeted way if some receiver turns out to be broken on tlsv1.3.
Recommended values

Set it only for a reason. There are exactly two reasons:

Value When
not set (default) always
tlsv1.2 the receiver announces tlsv1.3 and breaks on it
tlsv1.2 for reuse-ssl-session only one such receiver is known — Gmail; the gain is small, the version is lower

And record the reason next to it, as a comment: there will be nobody to remove the line in a year if it is unclear why it is there.

The values and the absence of a default are from the manual (§ 3.3.10.108.12). The connection with session reuse is from § 3.3.10.108.5; the advice to record the reason is ours.
Example configuration
# a workaround for a specific receiver's bug, with the reason next to it
<domain broken.example.com>
    use-starttls yes
    smtp-tls-max-version tlsv1.2   # announces 1.3 and breaks on it, checked 28.08</domain>
The comment here matters more than the line itself: without it, in half a year nobody will understand whether it can be removed. The receiver will get updated, but the restriction will remain.
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▶

Limiting the ceiling “just in case”

our experience

What it costsThe connection stays on an old version forever. The receiver gets updated, and the node keeps negotiating what it was told years ago.
How to spot itA receiver has a lower version than its fleet neighbors, for no visible reason.
How to do it rightDo not set it without a specific reason. When set, give it a comment with the date and the cause.

Lowering the ceiling for the sake of session reuse

§ 3.3.10.108.5

What it costsThe gain is a faster initial handshake when reconnecting to the same host; the price is a protocol version lower than possible. And according to the manual, only one known receiver supports this.
How to spot itThe ceiling is lowered without an explicit reason, the comment talks about performance.
How to do it rightKeep tlsv1.3 and do not use session reuse: on tlsv1.3 the handshake is faster anyway.
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
smtp-tls-max-version <enumeration>
Values
tlsv1 | tlsv1.1 | tlsv1.2 | tlsv1.3
Default
none, which behaves as tlsv1.3 § 3.3.10.108.12
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 directive lives in <domain> and merges by the usual rule for recipient blocks: the most precise match by receiver name wins. The same three levels apply by sending address — node, <virtual-mta-pool>, <virtual-mta>.
How to check on the node
The negotiated version is visible in accounting — that is how you check that the ceiling took effect:
pmtaacctfind --output csv[rcpt,dlvTlsProtocol] /var/log/pmta/acct-*.csv | head -20
For a receiver with a ceiling set, the version must not exceed it. If it was lower anyway, the line changed nothing — and is most likely not needed. The version column is filled only if dlvTlsProtocol is named in record-fields; on Hub nodes it is not named.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Connection encryption