GLPI Email Notifications: Complete Configuration Guide

Technical guide to email notifications in GLPI: SMTP, OAuth for Gmail and Microsoft 365, the event-queue-sending model, the queuednotification cron, SQL diagnostics and the field traps that keep email from arriving even when SMTP is correct.

In this article8 sections

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:

  1. Event - something happens (new ticket, follow-up, resolution) and a Notification matches the event with a Template and recipients.
  2. Queue - the message is written to the glpi_queuednotifications table, not sent immediately.
  3. 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:

ModeWhen to usePortMain caveat
PHP mail()Lab/local testing only-No auth/TLS; lands in spam - do not use in production
SMTPTrusted internal relay on the LAN25 or 587No encryption; closed networks only
SMTP + TLS (STARTTLS)External relay with authentication587Recommended default; validate the certificate
SMTP + SSLRelay that requires implicit TLS465Less common today, but functional
SMTP + OAuth 2.0Gmail / Microsoft 365587Requires 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:

SymptomLikely causeWhere to look
No email goes outQueue not draining / cron stoppedglpi_queuednotifications + queuednotification action
Authentication errorBasic auth blocked (Gmail/M365)Move to OAuth; enable SMTP AUTH on M365
Emails land in spamSender not authorized on the relay (SPF/DMARC)Align from_email with the relay domain
5.7.60 / SendAsDenied (M365)OAuth mailbox lacks "Send As" permissionGrant Send As or use its own address
Timeout on port 25Cloud provider blocks outbound 25Switch 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.

Frequently Asked Questions

The problem is almost never SMTP - it is the queue drain. Notifications go into the glpi_queuednotifications table and only leave when the queuednotification automatic action runs via cron. If the cron is stopped or the action is in GLPI mode on a low-traffic instance, the queue fills and nothing is sent. Run front/cron.php via an external cron every minute.

Use 587 with STARTTLS in most cases - it is the modern authenticated submission standard. Port 465 (implicit SSL) works with relays that require it. Avoid 25: besides having no encryption, almost every cloud provider blocks outbound port 25, which shows up as a send timeout.

Register an application in Azure (App Registrations), generate a Client ID and Secret, provide the GLPI redirect URI, and in GLPI use the SMTP+OAuth mode pointing to smtp.office365.com on port 587. The catch: M365 disables SMTP AUTH on the mailbox by default. Enable it with Set-CASMailbox -SmtpClientAuthenticationDisabled $false, otherwise sending fails even with correct OAuth.

In the interface, under Administration > Notification queue. In the database, query glpi_queuednotifications filtering by sent_time IS NULL - those are the messages that have not left yet. A large and growing pile with SMTP intact points to a stopped cron or the queuednotification action in GLPI mode.

The most common reason is the sender (from_email/admin_email) not being authorized to send through the relay used, which breaks SPF/DMARC. Set the sender address to a domain the SMTP server is allowed to send as, and align SPF, DKIM and DMARC in the domain's DNS.

For reliability, use CLI/external. GLPI mode triggers the cron on interface access; on an instance idle outside business hours, notifications are delayed or only leave when someone opens the system. An external cron calling front/cron.php every minute guarantees the drain regardless of traffic.

Need help?