HandshakeFailure indicates that the client and server could not agree on a common set of ciphers.
When using the default rustls TLS implementation, the cause of this is typically that the remote system is using legacy cipher suites that are not recommended for modern use.
OpportunisticInsecure TLS mode will not fall back to plain text after a failure to negotiate a connection because it is not always possible to do without opening a new connection, which can harm reputation.
In -dev builds, the error that you will see looks like this, with directive advice:
KumoMTA internal: failed to connect to any candidate hosts: All failures are related to OpportunisticInsecure STARTTLS. Consider setting enable_tls=Disabled for this site
You have a couple of options in this sort of situation:
Explicitly disable TLS for the destination, as recommended by the log entry. It’s no great loss because the possible ciphers are not sufficient for the modern internet.
Consider employing a shaping automation rule that will automatically set up option 1 for you, ready for the next attempt. Something like this will do that job; note that you need to be running a -dev build for this to work:
[["default".automation]]
regex="KumoMTA internal: failed to connect to any candidate hosts: All failures are related to OpportunisticInsecure STARTTLS. Consider setting enable_tls=Disabled for this site"
action = {SetConfig={name="enable_tls", value="Disabled"}}
duration = "30 days"
Also available to -dev builds, is the new tls_prefer_openssl option that can switch to the openssl backend. That may help you to handshake with these problematic sites, but you’re trading in some other compatibility and potential security pitfalls. If you opt to use this, you must ensure that you have configured an appropriate set of ciphers via the other new openssl related options.
just fyi: I changed for the latest stable version the following regex: "KumoMTA internal: failed to connect to any candidate hosts: .* after OpportunisticInsecure STARTTLS handshake",