If your Exim address rewrite is not working, the cause is usually one of four things: the rule is in the wrong place, the flags do not match the address type you think they do, you are expecting transport-time rewriting to change the envelope when it cannot, or routing and redirection are happening at a different stage than you assume. If your Exim client TLS errors appear at the same time, the usual pattern is similar: Exim is negotiating exactly what its configuration and TLS library allow, but the remote server, your certificate validation policy, or your own stack version is not aligned with that expectation.
Those two problems show up together more often than people expect because both live in the part of Exim that punishes vague mental models. Rewriting has precise stages. TLS has precise roles. If you know where Exim rewrites, when it routes, and which TLS options apply to the server side versus the SMTP client side, the failures stop looking random.
This guide goes deep on both topics. It covers how Exim rewriting actually works, why a rule that looks correct can still be skipped, how to test rewriting properly, how outbound TLS is negotiated by the smtp transport, and how to debug real delivery failures without guessing. The examples are written to stay close to the current Exim specification, not to forum folklore.
Why Exim rewriting is misunderstood so often
Exim has more than one place where an address can change, and those places do different jobs. The main rewrite section applies to addresses in incoming messages. A transport can also use headers_rewrite, but that is later and it only affects headers, not the envelope. The envelope sender can also be changed at transport time with return_path, but envelope recipients cannot be rewritten at transport time.
That distinction matters because many broken configurations are logically impossible, not merely misconfigured. If you expect a transport-time rule to change RCPT TO, Exim will not do it. If you expect a rule in the main rewrite section to modify headers added later by a router or transport, Exim will not do that either. Once you internalize those boundaries, most rewrite failures become much easier to diagnose.
The other trap is assuming that rewriting is a routing substitute. Exim supports rewriting, but its own documentation explicitly warns that using rewriting as a routing tool is strongly discouraged. That is the right instinct. If you need to choose a destination, think in terms of routers and transports first. Use rewriting for regularizing addresses, canonicalizing local identities, or carefully scoped header changes.
How rewriting actually happens in Exim
The core timeline is the part most administrators get wrong. A special SMTP-time rewrite rule using the S flag can change incoming envelope addresses as Exim receives MAIL FROM or RCPT TO. Ordinary rewrite rules are not the same thing. For normal rewriting, Exim applies the main rewrite section to incoming message addresses, and the permanent rewrite of envelope recipients happens once the message headers have been received. Exim also applies rewriting to child addresses generated by redirection unless the router is configured with no_rewrite.
Then there is transport time. A transport can apply headers_rewrite just before the message is written out, which affects original headers and headers added by ACLs or a system filter. It does not affect headers added by routers or transports. It also does not affect the envelope. If you need the outgoing envelope sender to differ, use return_path on the transport. If you need the outgoing envelope recipient to differ, solve that in routing, redirection, or address generation before the transport phase.
begin rewrite
# Canonicalize sender identities from an internal host to the public domain.
# Applies to envelope From plus From:, Reply-To:, and Sender: headers.
*@legacy.example.net ${local_part}@example.com Ffrs
This example is intentionally narrow. It does not touch recipient fields. It does not attempt to reroute mail. It simply regularizes sender identity for a known internal domain. That is the kind of rewrite Exim handles cleanly.
What the rewrite flags really mean
A rewrite rule is not just a pattern and a replacement. The flags determine whether the rule even gets considered for the address currently being processed. This is where many seemingly correct rules quietly fail. If you write a sender-only rule and then test a recipient path, the rule is not broken. It is being skipped because the flags do not match.
The high-value flags to remember are these:
Frewrites the envelope From field.Trewrites the envelope To field.f,r,s,t,c,btarget specific address-bearing headers.hmeans all address-bearing headers, not every header in the message.Sis special SMTP-time rewriting and must be treated separately.qstops further rewrite processing once the rule is invoked.Rreapplies the successful rule to the rewritten address, up to ten times.Qallows an unqualified local part as the rewritten result, which Exim then qualifies.
If you omit all header and envelope target flags in a main rewrite rule, the rule applies broadly to all address-bearing headers and both envelope sender and recipient fields. That can be useful, but it can also be a blunt instrument. For production mail systems, narrow rules are usually safer than global ones.
Common reasons an Exim rewrite rule does not work
1. The rule is in the wrong mechanism
If you put a rule in headers_rewrite and expect it to change envelope recipients, it will fail because that mechanism never touches the envelope. If you put a rule in the main rewrite section and expect it to change headers that a router adds later, it will fail because global rewriting only applies to the original incoming headers.
2. The flags do not match the address type being processed
A rule limited to F and f will not touch recipients. A rule limited to t and c will not change the envelope. This sounds obvious, but it is the single easiest way to create a rule that looks valid and does nothing in the scenario you are testing.
3. The replacement is not a full address when Exim requires one
Unless you deliberately use Q, the rewritten result must be a fully qualified address. A replacement that expands to only a local part is not accepted as a normal rewrite result.
4. You are confusing rewriting with routing or redirection
If your goal is to make mail for one domain deliver somewhere else, you may need router logic, redirection, aliases, or a transport decision instead of a rewrite. Exim can rewrite an address string, but delivery behavior is still controlled by routing. Those are not the same operation.
5. A control panel is regenerating your config
On DirectAdmin, cPanel, and similar systems, editing the wrong generated file is the fastest way to lose your changes on the next rebuild or template refresh. If your rule works briefly and disappears, or if the live config is not the file you edited, your problem may be config generation rather than Exim logic. Fix that before debugging the rule itself.
A safer way to build rewrite rules
Start narrow. Make the first rule obvious. Test it with a real address. Only then make it dynamic or lookup-driven.
begin rewrite
# Step 1: prove the mechanics with a single explicit rewrite
alice@legacy.example.net alice@example.com Ffrs
# Step 2: generalize once the first rule behaves correctly
*@legacy.example.net ${local_part}@example.com Ffrs
Once that works, you can move to a map-driven rule if you actually need per-user remapping rather than simple domain normalization.
begin rewrite
# /etc/exim/rewrite.map should return a fully qualified address in $value
*@* ${lookup{$local_part@$domain}lsearch{/etc/exim/rewrite.map}{$value}fail} Ffrs
The important constraint is that your lookup must return a fully qualified address. If your map returns only alice instead of alice@example.com, the rewrite is malformed unless you deliberately use the Q behavior and understand the qualification result.
How to test rewriting correctly
Use the right Exim tool for the right layer. This is where a lot of time gets wasted.
exim -brwtests input rewrite rules directly.exim -bttests routing of an address.exim -bvverifies a recipient using router logic.exim -d-all+rewrite+routegives focused debug output for rewrite and routing behavior.
# Test how the rewrite section transforms an address in each possible context
exim -brw alice@legacy.example.net
# Test routing for a recipient, optionally with a realistic sender
exim -bt -f sender@example.com recipient@example.net
# Focus debug output on the logic that usually matters here
exim -d-all+rewrite+route -bt -f sender@example.com recipient@example.net
-brw is the most underused command in Exim rewrite troubleshooting. It shows how the address would be transformed in each possible position, including envelope sender, envelope recipient, and relevant headers. That makes it much better than staring at the config and hoping. If -brw already shows the wrong behavior, fix the rule before you waste time chasing routers or transports.
-bt is different. It pushes the address through routing logic. That matters because a rewrite may be correct, yet the eventual delivery path may still surprise you due to routers, aliases, redirections, or no-address-test behavior. If your complaint is really "mail still goes to the wrong place," you probably need both -brw and -bt.
When you should use headers_rewrite instead
If your actual goal is to rewrite address-bearing headers as the message leaves through a specific transport, headers_rewrite is often the better tool. It is transport-scoped, which means it can be narrower and safer than a global rewrite rule. It also sees original headers plus headers added by ACLs or a system filter, which global input rewriting does not.
remote_smtp:
driver = smtp
headers_rewrite = *@legacy.example.net ${local_part}@example.com f : \
*@legacy.example.net ${local_part}@example.com r : \
*@legacy.example.net ${local_part}@example.com s
Use this pattern when you want a specific SMTP transport to regularize visible sender headers on the copy that leaves that transport. Do not use it when the real requirement is envelope-recipient rewriting. That requirement belongs earlier in Exim's processing.
How client-side TLS actually works in Exim
On the TLS side, the biggest misconception is thinking that the same TLS settings govern both inbound and outbound behavior. They do not. Exim's server-side TLS behavior is controlled by the main configuration options. Outbound TLS behavior lives in the smtp transport. That distinction is explicit in the current Exim specification.
As an SMTP client, Exim will try STARTTLS automatically when the remote server advertises it, unless you deliberately disable that for specific hosts with hosts_avoid_tls. If you require encryption for a host, you can enforce it with hosts_require_tls. If TLS negotiation fails after STARTTLS succeeds, what happens next depends on tls_tempfail_tryclear. If that is false, delivery is deferred. If it is true, Exim can reconnect and try cleartext for hosts that are not in hosts_require_tls.
This is why some administrators think Exim is "randomly" falling back to plaintext. It is not random. It is following documented transport behavior. If you do not want fallback, say so explicitly in the transport.
A sane TLS baseline for Exim server mode
For inbound SMTP, Exim needs to advertise STARTTLS and present a certificate and private key. Exim's current documentation says that STARTTLS is advertised to hosts matching tls_advertise_hosts, and that a working server-side TLS setup needs tls_certificate and tls_privatekey set to readable PEM files with full paths.
tls_advertise_hosts = *
tls_certificate = /etc/ssl/mail/mail.example.com.fullchain.pem
tls_privatekey = /etc/ssl/mail/mail.example.com.key
This is the server side only. It helps remote MTAs connect to you securely. It does not, by itself, define how your server verifies remote certificates when Exim is the SMTP client sending mail out.
A sane TLS baseline for the smtp transport
For outbound SMTP, keep the configuration explicit. If you need certificate verification for selected peers, set it in the smtp transport. Do not assume that the global certificate settings used for inbound SMTP will be reused automatically for client mode. Exim explicitly says it does not assume that.
remote_smtp:
driver = smtp
tls_verify_certificates = system
tls_tempfail_tryclear = false
That is a conservative baseline for a host where you want normal certificate validation and you do not want Exim to silently retry the same host in cleartext after a temporary TLS negotiation problem. If you need to enforce TLS only for a particular relay or smarthost, scope that requirement to the actual host list instead of forcing a global Internet-wide policy you do not control.
remote_smtp:
driver = smtp
hosts_require_tls = mail.relay.example.net
tls_verify_certificates = system
tls_tempfail_tryclear = false
If you set tls_require_ciphers, do it carefully. Exim's current documentation notes that when TLS 1.3 is negotiated, that option is ignored for TLS 1.3 cipher selection. Overly aggressive cipher tuning also tends to create compatibility problems faster than it solves them, especially on general-purpose Internet delivery.
Why Gmail often exposes your TLS problems first
Google is not the only destination that cares about SMTP hygiene, but it is often the first place where weak setups become visible. Google's sender guidelines say senders to Gmail should use a TLS connection for transmitting email, and they also require sane authentication and DNS hygiene such as SPF or DKIM and valid forward and reverse DNS. If your stack is marginal, Gmail is a common place to see the symptoms before smaller providers complain.
That does not mean every Gmail delivery issue is a TLS version problem. It means Gmail is a high-signal destination. If mail to smaller receivers succeeds while Gmail shows TLS or trust failures, that is often telling you your stack is only barely compatible elsewhere.
How to test a remote SMTP TLS endpoint properly
The fastest external check is openssl s_client with STARTTLS for SMTP. OpenSSL documents s_client as a diagnostic TLS client, and it is exactly the right tool for checking what a remote server actually negotiates.
openssl s_client -starttls smtp \
-connect gmail-smtp-in.l.google.com:25 \
-servername gmail-smtp-in.l.google.com
What you want to see is simple: a successful handshake, a usable certificate chain, and a negotiated protocol and cipher. If the connection dies before STARTTLS completes, or if the certificate chain is invalid, you already have evidence before you touch Exim. If the remote side looks fine with s_client but Exim still fails, the next step is to inspect Exim's own transport settings and debug output.
If you get a message like wrong version number, do not jump straight to "the remote server only supports old TLS." That specific OpenSSL family of errors often points to a protocol mismatch, such as trying to speak TLS directly to a service or proxy that is currently speaking plain SMTP, or testing the wrong port or wrong path through a load balancer. Treat it as a handshake-shape problem first, not a guaranteed cipher complaint.
How to debug Exim client TLS failures without guessing
When the failure is inside Exim and not obvious from s_client, turn on targeted debug categories instead of dumping everything.
exim -d-all+tls+route+transport -bt recipient@gmail.com
That is not a full delivery attempt, but it is a clean way to focus on how Exim is thinking. For queued mail or a controlled test delivery, use a staged approach. Check the main log, then increase debug only as much as needed. On busy systems, indiscriminate Exim debug output becomes noise very quickly.
Pay particular attention to these questions:
- Did the remote server advertise STARTTLS?
- Did Exim attempt STARTTLS and fail before handshake completion?
- Is Exim verifying the server certificate, and against which trust store?
- Is the failure only for one destination host, or for multiple modern receivers?
- Did your packaging or control panel recently change OpenSSL, GnuTLS, Exim, or certificate files?
If the breakage started after a major package change, treat it like an upgrade problem, not routine maintenance. That distinction matters. Server Update vs. Upgrade: What's the Difference and Why It Matters is worth reading before you make another round of live TLS changes on a production mail host.
What usually goes wrong in production
The same operational mistakes come up repeatedly.
- A rewrite rule is syntactically valid but attached to the wrong phase.
- The administrator tests routing with
-btbut never tests rewriting with-brw. - A panel regenerates Exim config and silently discards manual edits.
- The server presents a valid inbound certificate, but the outbound
smtptransport has different or incomplete trust settings. - An old TLS stack still works with permissive peers but fails when stricter receivers are involved.
- A fallback to cleartext is allowed by transport policy, so the operator misreads the actual security posture.
- Mail delivery symptoms are blamed on Exim when the real issue is DNS, reverse DNS, SPF, DKIM, or overall deliverability posture.
That last point matters more than many admins want to admit. If your mail server is custom-built and business-critical, you are no longer only managing Exim. You are managing the whole chain: certificates, DNS, queue behavior, authentication, reputation, and remote policy compatibility. Email Deliverability Guide: Why Your Hosting Matters is relevant here because many "TLS issues" turn out to be part of a broader outbound mail hygiene problem.
When managed help makes sense
If the problem is a single typo in a hand-maintained Exim config, fix it yourself and move on. If the problem spans Exim rewriting, outbound TLS, DNS, certificate trust, queue state, and panel-generated config, that is no longer a one-line repair. It is operational mail engineering.
That is the point where ServerSpan Linux Administration or ServerSpan DirectAdmin Management makes sense, depending on whether the system is a custom Linux stack or a DirectAdmin-managed server. If what you really want is to stop owning a self-managed Exim stack altogether, ServerSpan eMail Hosting is the cleaner answer. It is better to admit that a mail server is no longer worth hand-tuning than to keep patching a brittle one because you are already invested in it.
Final troubleshooting checklist
- Test the rewrite itself with
exim -brw. - Test routing separately with
exim -bt. - Confirm whether the change you want belongs in
rewrite,headers_rewrite,return_path, or a router. - Verify your flags match the actual address type you are testing.
- Use focused debug selectors such as
rewrite,route,tls, andtransport. - Test the remote peer independently with
openssl s_client -starttls smtp. - Check whether TLS requirements, certificate verification, or fallback policy are defined in the
smtptransport, not only in global Exim settings. - If the host is panel-managed, confirm your edits survive config regeneration.
Conclusion
Exim address rewriting stops being mysterious once you stop treating it as a single feature. There is input-time rewriting, SMTP-time rewriting, transport-time header rewriting, and transport-time return-path changes. They solve different problems. Exim client TLS errors also stop looking random once you separate server-side TLS from the smtp transport's client-side policy and verify what the remote endpoint is actually offering. Most broken setups are not broken because Exim is inconsistent. They are broken because the operator is asking one Exim mechanism to do a different mechanism's job.
If you are debugging a production mail host and the failure is no longer isolated to one obvious rule or one obvious certificate problem, stop improvising changes under live load. Use ServerSpan Linux Administration if you need expert help on a custom stack, or move to ServerSpan eMail Hosting if owning the mail stack is no longer worth the operational cost.
Source & Attribution
This article is based on original data belonging to serverspan.com blog. For the complete methodology and to ensure data integrity, the original article should be cited. The canonical source is available at: Mastering Exim: A Guide to Address Rewriting and Client TLS Errors.