Fedora CA Bundle Missing Symlink¶
Short version (rewritten 2026-10-23)
On Fedora 44, ca-certificates does not ship /etc/pki/tls/certs/ca-bundle.crt. If Postfix's smtp_tls_CAfile points there, any symlink you create to make it work is removed by the next ca-certificates update — and with smtp_tls_security_level = encrypt, all outgoing mail then queues silently.
Durable fix: point Postfix at the bundle the package owns and refreshes:
The symlink is only an emergency stopgap.
Symptoms¶
Postfix stops relaying to a TLS-required upstream. journalctl -u postfix shows:
postfix/smtp: cannot load Certification Authority data,
CAfile="/etc/pki/tls/certs/ca-bundle.crt",
CApath="/etc/pki/tls/certs": disabling TLS support
and every message is deferred with:
There's no bounce and no alert. postqueue -p slowly fills up, and you notice only because Logwatch, Fail2Ban or cron mail stops arriving.
Other TLS clients on the box (curl, dnf) are usually fine: they use the ca-trust paths, not this one. So don't assume a broken box just because the path is missing. Diagnose from the Postfix log error.
Diagnosis¶
# What is Postfix actually configured to use?
sudo postconf smtp_tls_CAfile smtp_tls_CApath smtp_tls_security_level
# Does that file exist?
ls -la /etc/pki/tls/certs/ca-bundle.crt
# The package-owned bundle — should always exist
ls -la /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
rpm -qf /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem # → ca-certificates
# When did ca-certificates last change?
rpm -q --last ca-certificates
You've found it if all three of these are true:
smtp_tls_CAfilenames a path that doesn't exist.- The log shows the error above.
smtp_tls_security_level = encrypt(or the relay needs TLS, e.g. port 465 withsmtp_tls_wrappermode = yes).
Why it happens¶
/etc/pki/tls/certs/ca-bundle.crt is an old consumer path. On Fedora 44 the ca-certificates package ships /etc/ssl/certs/ca-bundle.crt and the files under /etc/pki/ca-trust/extracted/, but not this path. A symlink created there by hand belongs to no package, and a ca-certificates update can remove it. This happened twice on the same three relay hosts:
- 2026-09-04: found missing; the symlink was recreated by hand.
- 2026-10-23: the
ca-certificates-2026.2.92_v9.0.319-2.fc44update in a routine fleetdnfrun removed it again. Mail on all three hosts was held for about 9 hours.
Recreating the symlink just resets the clock until the next update.
Fix (durable)¶
Point Postfix at the package-owned bundle, check the config, and reload. A reload keeps the queue and open connections; a restart isn't needed.
sudo postconf -e 'smtp_tls_CAfile = /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem'
sudo postfix check && sudo systemctl reload postfix
sudo postqueue -f # retry the deferred mail now
Leave smtp_tls_CApath alone unless postfix check complains.
To make sure the next config run doesn't put the old path back, set it in config management too. In MajorAnsible, the postfix_relay role does this for the Fedora relay clients. It uses a RedHat-only lineinfile with backup: true, and a handler that runs postfix check before systemctl reload postfix:
- name: Set SMTP TLS CA file to the package-owned bundle (RedHat)
ansible.builtin.lineinfile:
path: /etc/postfix/main.cf
regexp: "^smtp_tls_CAfile\\s*="
line: "smtp_tls_CAfile = /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"
backup: true
when: ansible_facts['os_family'] == "RedHat"
notify: Reload Postfix
Emergency stopgap¶
If you can't change the Postfix config right now:
sudo ln -sf /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
/etc/pki/tls/certs/ca-bundle.crt
sudo postqueue -f
This will break again on a later ca-certificates update. Follow up with the durable fix.
Verify¶
sudo postconf smtp_tls_CAfile # shows the ca-trust path
sudo journalctl -u postfix --since "-10min" | grep -c "disabling TLS support" # 0 after the reload
sudo postqueue -p # "Mail queue is empty" after a minute or two
Then confirm the held messages actually arrived at the destination mailbox.
Fleet audit¶
Check every Fedora Postfix host for a CAfile that points at a missing file:
for host in majorlab majorhome majordiscord majormail; do
echo "== $host"
ssh root@$host 'f=$(postconf -h smtp_tls_CAfile); echo "CAfile=${f:-<unset>}"; [ -z "$f" ] || [ -e "$f" ] || echo " MISSING — mail will defer"'
done
An empty smtp_tls_CAfile is fine (majormail runs that way). Only a value that names a file that doesn't exist is the problem.
Related¶
- Logwatch Fleet Setup: Logwatch mail depends on a working Postfix relay
- VPS Migration Baseline Checklist: verify TLS works, not a specific path