In GLPI, "setting up email" is not just pointing at an SMTP server - it is making sure the event becomes a message, enters the queue and actually leaves. While supporting client environments, most "GLPI stopped sending email" cases have nothing wrong with SMTP: what broke was the queue drain or the cron. This guide covers the full configuration and, above all, the points where delivery truly fails.
The mental model: event, queue and sending
A notification goes through three stages, and each one fails differently:
- Event - something happens (new ticket, follow-up, resolution) and a Notification matches the event with a Template and recipients.
- Queue - the message is written to the
glpi_queuednotificationstable, not sent immediately. - Sending - the automatic action
queuednotification, triggered by the cron, drains the queue over SMTP.
Keep that separation in mind: most of the incidents we handle live in stage 3 (the queue fills and nobody drains it), not in stage 1 (SMTP). Configuring a perfect SMTP without securing the cron is the classic recipe for "I set up everything and nothing arrives".
Base SMTP configuration
Under Setup > Notifications > Email followups configuration, enable email follow-ups and fill in:
- Sending mode: SMTP+TLS in most cases - avoid PHP
mail()in production. - Server and port: the relay host + 587 (STARTTLS) or 465 (SSL).
- Login/password or OAuth: depending on the provider.
- Administrator and sender email: an address the relay is authorized to send as - that detail decides whether the email arrives or lands in spam.
The password is stored encrypted (GLPIKey) in the smtp_passwd column. Never read it via SQL: it comes scrambled and does not help diagnosis. To check the rest of the configuration straight from the database:
-- Sending configuration check (never read smtp_passwd: it is encrypted)
SELECT name, value
FROM glpi_configs
WHERE context = 'core'
AND name IN ('smtp_mode','smtp_host','smtp_port','smtp_username',
'smtp_check_certificate','admin_email','from_email',
'notifications_mailing','use_notifications');
If notifications_mailing comes back as 0, email notifications are globally disabled - no SMTP setting matters until you turn it on.
Choosing the sending mode
This is the matrix we use to pick the mode per scenario:
| Mode | When to use | Port | Main caveat |
|---|---|---|---|
| PHP mail() | Lab/local testing only | - | No auth/TLS; lands in spam - do not use in production |
| SMTP | Trusted internal relay on the LAN | 25 or 587 | No encryption; closed networks only |
| SMTP + TLS (STARTTLS) | External relay with authentication | 587 | Recommended default; validate the certificate |
| SMTP + SSL | Relay that requires implicit TLS | 465 | Less common today, but functional |
| SMTP + OAuth 2.0 | Gmail / Microsoft 365 | 587 | Requires App Registration + SMTP AUTH enabled (M365) |
Gmail and Microsoft 365 via OAuth 2.0
Gmail and Microsoft 365 have blocked basic authentication (login + password). The supported path is OAuth 2.0 (GLPI 10.0.7+). At the provider you register an application (Google Cloud Console or Azure App Registrations), generate a Client ID and Client Secret, provide the GLPI redirect URI and authorize. In GLPI, choose the SMTP+OAuth mode, select the provider and paste the credentials.
The trap that eats the most time on Microsoft 365: even with correct OAuth, M365 disables SMTP AUTH by default on the mailbox. Without enabling it, authentication passes and sending fails. Enable it on the mailbox in use:
# Microsoft 365: enable SMTP AUTH on the mailbox used by OAuth (disabled by default)
Set-CASMailbox -Identity [email protected] -SmtpClientAuthenticationDisabled $false
On Gmail/Workspace the scope is https://mail.google.com/ and, on Workspace accounts, the admin may need to allow the app. Accounts with 2FA still accept an app password as a fallback, but Google is phasing that path out.
The queue and the cron: where it really breaks
Here is the detail that only shows up in operations. The queuednotification automatic action can run in two modes: GLPI (triggered by interface access) or CLI (via external cron). On a low-traffic instance - the client that only uses GLPI during business hours - GLPI mode means the overnight notifications only leave when someone opens the system in the morning. The symptom arrives as "email delayed" or "not arriving". The decision we standardized in support: all automatic actions in CLI mode, with front/cron.php called by an external cron every minute.
# GLPI - drain the notification queue every minute (run as the web server user)
* * * * * www-data /usr/bin/php /var/www/glpi/front/cron.php >/dev/null 2>&1
# In Docker: fire the GLPI cron as the web server user (adjust name/path)
* * * * * root docker exec -u www-data glpi php /var/www/glpi/front/cron.php >/dev/null 2>&1
To see whether the queue is draining, look at what is stuck without sent_time:
-- Notifications stuck in the queue (a full queue = cron is not draining it)
SELECT id, itemtype, recipient, create_time, send_time, sent_time, sent_try
FROM glpi_queuednotifications
WHERE sent_time IS NULL
ORDER BY send_time ASC
LIMIT 20;
A large and growing pile here, with SMTP intact, is almost always a stopped cron or GLPI mode. You can also follow it in the interface under Administration > Notification queue.
Templates and variables
Under Setup > Notifications > Notification templates you edit the body of each event. Variables use the ##...## syntax:
<!-- "New ticket" template - HTML body with GLPI variables -->
<p>Hello ##ticket.author##,</p>
<p>Your ticket <strong>##ticket.id##</strong> has been registered:</p>
<ul>
<li>Title: ##ticket.title##</li>
<li>Priority: ##ticket.priority##</li>
<li>Track it at: ##ticket.url##</li>
</ul>
A template can have per-language versions; without the version for the recipient's language, GLPI uses the default one. The common mistake here is editing only the Portuguese body and then wondering why the technician with an English profile receives the old template.
Field traps
The symptoms we see most and where to investigate each one:
| Symptom | Likely cause | Where to look |
|---|---|---|
| No email goes out | Queue not draining / cron stopped | glpi_queuednotifications + queuednotification action |
| Authentication error | Basic auth blocked (Gmail/M365) | Move to OAuth; enable SMTP AUTH on M365 |
| Emails land in spam | Sender not authorized on the relay (SPF/DMARC) | Align from_email with the relay domain |
| 5.7.60 / SendAsDenied (M365) | OAuth mailbox lacks "Send As" permission | Grant Send As or use its own address |
| Timeout on port 25 | Cloud provider blocks outbound 25 | Switch to 587 (STARTTLS) |
| Technician does not get their own update | "Do not notify the author of the action" | Expected behavior, not a bug |
A word on the last case: by default GLPI does not notify the author of their own action. The technician who updates the ticket does not get the echo of their own update - that is expected behavior, not a bug. Mistaking it for "broken notifications" has already cost a late-night diagnosis chasing a problem that did not exist.
Beyond email
Email is asynchronous and competes for attention with the inbox. For the technician to see the ticket the instant it changes, email is not the best channel. Consider real-time notification with the Smart Notify module (bell in the navbar) or delivery via WhatsApp and Telegram for the events that cannot wait for the next email cycle.
If email from your GLPI environment is intermittent - sometimes it arrives, sometimes not - it is usually the queue and the cron, not the SMTP. NexTool handles GLPI support with notification-queue monitoring and the cron under control. Talk to us about GLPI support and maintenance.
Reviewed by the NexTool Solutions team.