Bali, Indonesia
Insights

systemctl Says Postfix Is active (exited), but Is Mail Actually Running?

October 28, 2026
0:00
You restart Postfix, run systemctl status postfix, and get a green active (exited). The ticket looks ready to close. On Debian and Ubuntu, though, that line tells you very little about whether mail is flowing. The unit you just checked is a wrapper. The process that actually listens on port 25 runs under a different unit, and that unit can be dead while the wrapper still looks fine. This catches support staff at every level. The restart command returns cleanly, nothing red shows up on screen, and the customer is told mail is back. An hour later they report bounces or a queue that never drains. The rest of this guide is a short, repeatable way to check the real state before you say anything is fixed.
Postfix supports multiple instances: separate copies of the mail system on one host, each with its own config directory and queue. Debian and Ubuntu model this in systemd with a template unit called [email protected]. The text after the @ is the instance name. The default instance, the one almost every server runs, is named -, so its unit is [email protected]. On these distros, postfix.service is mostly a grouping unit. It typically has Type=oneshot, an ExecStart that runs /bin/true, and RemainAfterExit=yes. In plain terms, systemd runs a command that does nothing, sees it succeed, and marks the unit active from then on. That is what active (exited) means: the start command finished and the unit is considered up, but no long-running process belongs to it. The real Postfix master daemon, which spawns smtpd, qmgr, and the rest, runs under [email protected]. Starting or restarting the wrapper pulls that instance along with it. If the instance fails, for example because of a syntax error in main.cf, a missing lookup table, or a port already in use, the wrapper usually stays active (exited). It has no process of its own to lose. On RHEL-family systems, postfix.service usually runs the master process directly, so this split does not apply. The checks below still work. The instance-specific commands will just report that no such unit exists.
Start by confirming how your server is wired, then look at the unit that matters. All of these commands are read-only.
BASH
# Show the wrapper unit file; look for ExecStart=/bin/true and RemainAfterExit=yes
systemctl cat postfix.service

# List every Postfix-related unit, including inactive and failed ones
systemctl list-units --all 'postfix*'

# Status of the default instance, where the master process actually runs
systemctl status [email protected]

# Script-friendly checks: each prints a single word such as active or failed
systemctl is-active [email protected]
systemctl is-failed [email protected]

# If more than one instance might exist, list them (needs root)
sudo postmulti -l
The list-units output is the fastest way to spot the problem. A healthy server shows postfix.service as active exited and [email protected] as active running. A broken one often shows the wrapper still active exited next to the instance as failed, or activating if it keeps crashing and restarting. In the systemctl status [email protected] output, read the Active: line and the process tree under CGroup:. When Postfix is really up, you should see a master process and usually qmgr and pickup under it. An empty process tree, or an Active: line that says failed with a recent timestamp, means mail is down no matter what the wrapper says. If you write a monitoring check or a post-restart script, point it at [email protected] with systemctl is-active. A check against postfix.service will report success even when the instance is dead.
Once you know the instance failed, the reason is almost always in its own log, not the wrapper's. The wrapper's journal usually just shows that it started and exited, which you already know.
BASH
# Recent log lines for the instance unit since the last boot
journalctl -u [email protected] -b --no-pager -n 50

# Postfix's own view of whether the master process is running
sudo postfix status

# Check config files, permissions, and ownership without starting anything
sudo postfix check
In the journal, look for lines tagged postfix/master or postfix/postfix-script that start with fatal: or error:. Common causes include an unreadable or missing .db lookup file that was never rebuilt with postmap, a typo in a main.cf parameter, bind: Address already in use when another MTA such as Exim or Sendmail still holds port 25, or permission problems under /var/spool/postfix. postfix status asks Postfix directly whether its master process is alive, so it does not depend on how systemd labels anything. postfix check validates the config and file permissions. It is a good first step after any edit and is safe to run on a live server. On some Debian and Ubuntu setups, Postfix also logs through rsyslog to /var/log/mail.log. If the journal looks thin, check that file for the same fatal: lines. Where logs go depends on the release and how logging was configured, so verify on your own server rather than assuming.
A running unit is necessary but not sufficient. Postfix can be up and still not accept mail from the internet. The smtp service might be commented out in master.cf, or inet_interfaces might be set so Postfix listens only on loopback. So check the socket itself.
BASH
# Listening TCP sockets on port 25 and the owning process (-p needs root)
sudo ss -ltnp 'sport = :25'

# Submission ports, if this server accepts authenticated clients
sudo ss -ltnp '( sport = :587 or sport = :465 )'

# Which interfaces and protocols Postfix is configured to bind (read-only)
postconf inet_interfaces inet_protocols
In a healthy result, each port shows a LISTEN line with a local address of 0.0.0.0:25, [::]:25, or the server's public IP, and a process name of master. There are a few other patterns to recognize:
  • No output at all: nothing is listening. If the instance unit shows as running, look at master.cf.
  • Only 127.0.0.1:25 or [::1]:25: Postfix is listening on loopback only. Local scripts can send mail, but nothing from outside can connect. Compare this with the inet_interfaces value.
  • A process other than master on port 25: another mail server is holding the port. This often explains a bind error in the journal.
The ss check only proves the socket exists on this host. A firewall, a security group, or a provider-level block on port 25 can still stop outside connections. For the last check, connect from a different machine with a plain TCP client such as nc or telnet and confirm you get a 220 SMTP greeting. The exact client and flags vary by distro, so use whatever is installed. If the banner appears locally but not remotely, the problem is no longer Postfix.
The rule of thumb is simple. Do not trust postfix.service on Debian or Ubuntu. Before you tell anyone mail is working, confirm three separate things: [email protected] is active (running) with a master process in its tree, the journal for that instance shows no fresh fatal: lines, and ss shows master listening on port 25 on the address you expect. If any of those is missing, the restart did not fix anything. It just hid the failure behind a wrapper that has nothing to fail. Teach junior staff to run these checks as one habit after every Postfix restart, and point monitoring at the instance and the socket instead of the wrapper.