How to Configure Nagios Notify by Email Step by Step
A freshly installed Nagios server can look healthy on screen and still stay eerily quiet in every inbox. The dashboard turns red, the service state changes, and nothing arrives because Nagios email alerting is a pipeline, not a switch. The operator has to verify the OS mailer, the Nagios command definitions, the contact record, and the delivery path before trusting any alert.
That layered model is why a good setup feels less like “turn on email” and more like building a chain you can inspect from end to end. If the alerting path is part of a broader monitoring practice, the same logic applies to everything from uptime to escalation, including basic context like what is server uptime and how monitoring reacts when services drift. It also helps to keep host security boundaries in mind, especially when the mailer runs under a restricted service account, as discussed in this SELinux vs AppArmor guide.
Table of Contents
- Why Nagios Emails Disappear and How This Guide Fixes It
- Preparing the Server Mailer and SMTP Relay
- Defining the notify-host-by-email and notify-service-by-email Commands
- Building a Contact and Attaching It to Hosts and Services
- Testing Notifications and Verifying Real Delivery
- Fixing the Most Common Email Notification Failures
- Leveling Up with HTML Templates, Escalations, and Integrations
Why Nagios Emails Disappear and How This Guide Fixes It
A junior admin often discovers the problem at the worst possible moment. Nagios is already showing CRITICAL, the team is checking the screen, and the inbox stays empty because the notification path was never fully wired. That failure usually isn't one broken setting, it's a missing link somewhere in a chain that starts outside Nagios and ends at an actual mail server.
Think in layers, not in toggles
Nagios email notifications depend on a local mail transport, then on command definitions, then on contact data, and finally on delivery. Red Hat's Nagios mail notification guidance shows the classic pattern clearly, edit commands.cfg, restart Nagios, and the server sends notifications to the mail addresses listed in the contact file, which reflects the old-school model where the operator had to wire contacts and commands together explicitly. That design matches the early-2000s monitoring mindset, where email was the default asynchronous escalation channel before chat and webhooks became common, and the same workflow still appears in later guides and distro-specific documentation from Red Hat.
The practical takeaway is simple. When a message never arrives, the first question is never “Did Nagios work?” The right question is “Which layer failed, the mailer, the command hook, the contact definition, or the recipient side?”
Practical rule: treat every silent alert as a pipeline outage until proven otherwise. That mindset saves time because each layer has a different failure signature.
Nagios support guidance and deployment notes both reinforce that the OS mailer matters just as much as the monitoring daemon. A mailer daemon has to be present on the server, and many environments still rely on Postfix or Sendmail to relay messages onward, especially when the final destination is an enterprise mail system. The rest of the setup follows that path in order, so the rest of this guide mirrors the same structure rather than dumping config fragments with no context.
Preparing the Server Mailer and SMTP Relay
A Nagios alert can look configured and still vanish before it reaches anyone. The usual failure point is the server mail path, where the operating system has no mailer, the MTA is misconfigured, or the relay refuses the message even though commands.cfg looks correct. Production setups start there because Nagios only hands the alert to the local mail stack, it does not deliver email on its own.
Install a local mailer first
Nagios support guidance says a mailer daemon has to be installed before email alerts can leave the server, and common deployments still use Postfix or Sendmail as the relay layer. In practice, that matters most in environments where direct outbound mail is blocked and the server must pass messages to a smart host or SMTP relay. The point is a reliable handoff from Nagios to the operating system, then from the operating system to the relay.
The binary path matters as well. A Debian 10 and Ubuntu 20.04 setup guide checks that mail resolves to /usr/bin/mail before testing a custom notification from the web UI, so the OS path has to be correct before any Nagios command can succeed Akamai's Nagios alert setup guide.
A real test sequence is straightforward:
- Confirm the mail package or MTA is installed.
- Confirm
/usr/bin/mailexists. - Send a short message to a real mailbox.
- Review the mail log or journal for a successful handoff.
- Only after that, move into Nagios configuration.
On a host that is missing the binary, the shell test fails immediately. On a host with a working binary but no relay access, the message may be accepted locally and then stall with log entries such as a connection timeout, relay access denied, or status=deferred while the MTA waits for permission to hand it off. That distinction matters, because it tells you whether to fix the local package, the relay policy, or the network path.

Relays matter more than direct delivery
Many production networks block direct port 25 delivery, so a smart host is the normal path rather than a workaround. Postfix can relay to an enterprise mail system, and Sendmail can do the same when it is already the standard MTA on the host. If the relay rejects the message, the failure is still below Nagios, which narrows the search quickly.
Host-based security can break mail in subtle ways. If outbound connections are blocked locally, the MTA may look installed and running while the relay never receives the message, so firewall policy and service permissions need to match the mail path. A host-based firewall review, such as the one in the host-based firewall guide, is a good check here because outbound mail traffic often fails before anyone notices the Nagios side is fine.
Real relay failures usually leave a trace. You may see connect to mx.example.com[...]:25: Connection timed out, 550 relay not permitted, or a message queued locally with no remote acceptance. Those logs point at the mail layer, not the notification command, and that saves time when alerts stop after a configuration change or a firewall tightening.
A solid mailer test gives a clear answer. If the message leaves the shell and appears in the mail logs, the OS layer is working and Nagios can use it. If not, fix transport first, then return to notification commands.
Defining the notify-host-by-email and notify-service-by-email Commands
Nagios email notifications are driven by two command definitions, notify-host-by-email and notify-service-by-email. These blocks aren't decoration in commands.cfg, they're the actual glue between a status change and a message that includes the right host, service, and recipient details. Nagios ships them as examples because administrators are expected to uncomment, adapt, or rewrite them for the local mailer path.
Read the macros like variables
The macros are the reason these commands work per alert instead of as a fixed message. \$CONTACTEMAIL$ supplies the recipient, \$HOSTALIAS$ or \$HOSTNAME$ identifies the target, and \$SERVICEOUTPUT$ carries the service check output into the body. That's also why the message subject can be different for host and service alerts, because each command can use a different set of macros depending on the object type.
A practical version usually looks like this:
define command {
command_name notify-host-by-email
command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **" $CONTACTEMAIL$
}
define command {
command_name notify-service-by-email
command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$\n" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$
}
Those commands match the standard Nagios workflow documented in distro and vendor guides, including the common pattern of using mail as the delivery binary Red Hat's Nagios mail notification guide and the Debian and Ubuntu alert setup reference from Akamai.
Operator habit: keep the subject short and the body informative. The subject should tell the on-call person what changed, while the body should provide enough context to avoid a second login.
Keep the command path boring
The safest command definition is the one that depends on the fewest moving parts. Hard-coding a known mail path, using plain macros, and avoiding custom shell logic makes failures easier to isolate. If the command works in a shell but not from Nagios, the mismatch is often permissions or object wiring, not the mail syntax itself.
That's why commands.cfg is so important. It isn't a template library, it's the handoff point between monitoring state and message generation, and when it's correct the rest of the stack can do its job without extra guesswork.
Building a Contact and Attaching It to Hosts and Services
Nagios still won't mail anyone until a contact object points to the right address and notification commands. That's the part people skip when they see the commands working in isolation. A clean alert pipeline only matters if the host or service references the contact through a contact group or direct association.
Define the recipient in contacts.cfg
The contact record carries the destination address and the notification hooks. A typical setup includes the email field plus host_notification_commands and service_notification_commands, and it should also specify the notification period so alerts happen only when the schedule allows them. The command names have to match what was defined in commands.cfg, otherwise Nagios has a valid-looking contact that never sends anything.
A straightforward contact entry might look like this in structure, though the local naming can vary:
- Contact name: a readable identifier for admins.
- Email field: the mailbox that should receive alerts.
- Host notification commands: the host alert command list.
- Service notification commands: the service alert command list.
- Notification period: the time window when messages are allowed.
The contact then needs to belong to a contact group, and that group has to be attached to the host or service definition that should trigger mail. Without that final attachment, Nagios can detect the problem and still have nowhere to send it.
Don't miss global notification state
The cleanest config in the world does nothing if notifications are disabled at the global or object level. That check is easy to overlook because the host or service may still change state correctly in the UI, which gives a false sense that alerting is already active. The test is whether the object inherits notifications from the right template and whether the contact group is part of the alert path.
A useful mental model is to trace the alert the same way Nagios does. First it evaluates the object, then it looks for notification eligibility, then it walks through the contact or contact group, and only then does it run the command that points at the OS mailer. If any one of those links is missing, the inbox stays quiet.
The most common configuration mistake is not the email address. It's the missing connection between the contact object and the monitored host or service.
For multi-object environments, consistent naming pays off. A single contact group can be shared across several hosts and services, but only if the object definitions are tidy enough that the alert path is obvious when troubleshooting. That habit makes later audits much faster, especially when several people are editing the Nagios config tree.
Testing Notifications and Verifying Real Delivery
The Send Custom Notification button in the Nagios web UI is one of the best debugging tools available because it isolates the notification layer from the actual service state. It lets an administrator test the pipeline without waiting for a real outage, and that matters when the goal is to prove delivery rather than simulate production failure. A web UI test should be paired with log inspection, because a message can leave Nagios and still die downstream.

Use the UI, then verify the logs
A good test flow starts with a custom notification from the Nagios interface. If that succeeds, the next stop is /var/log/maillog or the service journal for Postfix or Sendmail, where delivery status and any SMTP rejection details should appear. A bounced or deferred message tells a different story from a missing message, because one means the mailer accepted the job and the other means it never got that far.
That distinction matters when a message disappears between systems. If the log shows successful handoff but the inbox never gets the alert, the issue is usually recipient-side filtering, relay policy, or authentication rather than the Nagios command itself. If the log is empty, the problem is probably still in the OS mailer or the command path.
Compare UI testing with a real state change
A custom notification proves the alert command path, but a real service transition proves the whole object chain. If the service check moves from OK to a failure state and a notification arrives, that confirms the command, contact, notification schedule, and mail transport all work together. If the UI test succeeds but the state-change alert does not, the contact or service notification wiring deserves a second look.
The same testing rhythm applies in modernized deployments, including setups that route mail through Gmail SMTP with TLS and app passwords as described in Nagios Log Server documentation. A clean test isn't just about receiving one message, it's about knowing which layer produced it and which layer still needs attention.
Fixing the Most Common Email Notification Failures
Most Nagios mail failures fall into a small set of patterns. The noise comes from the symptoms, not the causes. A message can fail because the daemon lacks access, because the mailer returns a non-zero status, because the SMTP relay rejects unauthenticated traffic, or because the recipient side parks the alert in spam after SPF or DMARC checks fail.
Triage by symptom
| Common Nagios Email Failures and Fixes | ||
|---|---|---|
| Symptom | Root Cause | Fix |
| Alerts never leave the server | Nagios can't reach a working mailer or the binary path is wrong | Verify the mailer is installed and confirm the command points to /usr/bin/mail |
| Notification command runs, but nothing arrives | The mail command exits with an error or the relay rejects the handoff | Check the mail logs and fix relay authentication or transport settings |
| Gmail or Office 365 rejects the message | SMTP relay expects authenticated submission | Configure the relay with valid credentials and TLS |
| Message lands in spam | Recipient-side SPF or DMARC handling treats the alert as suspicious | Align the sender and relay policy, then review the junk folder |
Nagios support guidance makes the first failure mode easy to understand, because the server must have a mailer daemon installed before it can send anything. Debian and Ubuntu guides also call out the /usr/bin/mail path explicitly, which is a useful sanity check when the command appears correct but the binary doesn't resolve Akamai's guide.
Check the service account and relay trust
A subtle issue appears when Nagios is not running with enough access to reach the mail binary or hand off to the relay. That can show up as a working mail command from root and a failed notification inside Nagios, which is why permissions and service context matter. Recipient-side validation can also be the hidden culprit, and a DNS, certificate, or mail trust issue in the surrounding path may be the reason the alert never lands where it should, a useful reminder from adjacent Linux trust and certificate troubleshooting like this Linux certificate guide.
The cleanest fix path is linear. Check the log, identify whether the failure is local or remote, and then only change one layer at a time. That keeps the diagnosis short and avoids the common mistake of changing Nagios macros when the relay is the thing refusing mail.
Leveling Up with HTML Templates, Escalations, and Integrations
Once plain text alerts are flowing, the next wins are all about readability and routing. Nagios can send richer mail, assign a secondary contact when the issue persists, and hand the same event off to a script that forwards it into other systems. The pipeline stays the same, but the message becomes more useful to the person receiving it.
Make the email easier to scan
An HTML template gives the alert more structure, especially when the mailbox is crowded. A colored state header, a logo, and a clean layout can make it easier for a responder to spot the current status without parsing a block of plain text. The trade-off is that HTML emails are a little more work to maintain, so they belong after the basic notification path is already stable.
Escalations are the other high-value layer. They let Nagios send repeated alerts to a different contact or group when the first notification doesn't resolve the incident, which is useful for off-hours coverage or secondary response paths. That logic belongs in the notification policy, not in ad hoc operator behavior, because the system should know when to widen the circle.
Extend the same alert to other tools
Nagios doesn't have to stop at email. A notify-by-command hook can call an external script that posts the same event into a webhook, ticketing system, or chat platform, which is a common fit for teams that want one source of truth but multiple notification surfaces. For operators who prefer push channels for urgent incidents, a tool like Pushover notifications for Nagios is a natural companion to email because it preserves the same alert source while changing the delivery path.
For broader operations teams, this is also where centralized monitoring platforms make sense. In environments that want network monitoring for SMBs with multiple delivery options, IT Cloud Global's NOC overview is a useful reference point for how alert routing, escalation, and response workflows are often organized outside of a single mail channel. Fivenines fits that same operational pattern as one option for server alerting and notifications, including email delivery as a notification channel.
Bottom line: keep email as the base layer, then add HTML, escalation, or integrations only after the original pipeline is proven.
The lesson in Nagios notify by email is that reliable alerting comes from understanding the layers, not from trusting a checkbox. Fivenines brings that same mindset to server alerting, with email notifications, routing, and other delivery options in one monitoring stack. If the current setup still leaves gaps between the service state and the inbox, visit Fivenines and compare it with the alerting workflow already in place.
If Nagios email notifications keep going silent, Fivenines gives teams a cleaner way to route server alerts, including email, without stitching together the OS mailer and notification logic by hand. For operators who want a practical monitoring stack that's easier to verify and maintain, the next step is to visit Fivenines and see how it handles alert delivery end to end.