Skip to content

Requests to /ajax/notifications_ajax.php return a 500 error when session is expired #21557

@dani

Description

@dani

Code of Conduct

  • I agree to follow this project's Code of Conduct

Is there an existing issue for this?

  • I have searched the existing issues

Version

11.0.1

Bug description

When a user session expires, but the user left the tab opened, the browser still send regular (1/min) GET requests on /ajax/notifications_ajax.php. Those requests gets a 500 error (instead of 401 or 403). This can trigger alerts when you monitor the 5XX error rate

Relevant log output

in php-error.log, I can see this

[2025-10-20 16:26:42] glpi.CRITICAL:   *** Uncaught PHP Exception Glpi\Exception\SessionExpiredException: "" at Session.php line 1068
  Backtrace :
  ./src/Session.php:1068                             
  ./src/Session.php:1182                             Session::checkValidSessionId()
  ./src/Glpi/Http/Firewall.php:144                   Session::checkLoginUser()
  ...trollerListener/FirewallStrategyListener.php:82 Glpi\Http\Firewall->applyStrategy()
  ...ymfony/event-dispatcher/EventDispatcher.php:260 Glpi\Kernel\Listener\ControllerListener\FirewallStrategyListener->onKernelController()
  ...ymfony/event-dispatcher/EventDispatcher.php:220 Symfony\Component\EventDispatcher\EventDispatcher::Symfony\Component\EventDispatcher\{closure}()
  ...symfony/event-dispatcher/EventDispatcher.php:56 Symfony\Component\EventDispatcher\EventDispatcher->callListeners()
  ./vendor/symfony/http-kernel/HttpKernel.php:169    Symfony\Component\EventDispatcher\EventDispatcher->dispatch()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

Page URL

No response

Steps To reproduce

  1. Log into GLPI, and open for example the main ticket page (/front/ticket.php)
  2. Leave the tab open
  3. Wait for the session to expire
  4. See that requests to /ajax/notifications_ajax.php now gets a 500 error

Your GLPI setup information

GLPI information
GLPI: 11.0.1 ( => /app)
Installation mode: TARBALL
Current language: fr_FR
Source Integrity: 4 files changed
  A: bin/init-db
  A: inc/downstream.php
  D: install/install.php
  A: public/sso.php
Server
Operating system: Linux 24485edd080a 5.14.0-570.44.1.el9_6.x86_64 #​1 SMP PREEMPT_DYNAMIC Wed Sep 17 10:32:11 EDT 2025 x86_64

PHP: 8.3.26 fpm-fcgi

PHP extensions: Core, date, libxml, pcre, zlib, filter, hash, json, random, readline, Reflection, SPL, session, cgi-fcgi,
bcmath, bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, ldap, mbstring, openssl, PDO, posix, standard, SimpleXML, sockets,
sodium, tokenizer, xml, xmlwriter, zip, exif, mysqlnd, Phar, xmlreader, mysqli, pdo_mysql, igbinary, msgpack, redis, Zend
OPcache

Setup: disable_functions="system, show_source, symlink, exec, dl, shell_exec, passthru, phpinfo, escapeshellcmd"
max_execution_time="180" max_input_vars="1000" memory_limit="384M" post_max_size="8M" session.cookie_secure="0"
session.cookie_httponly="1" session.cookie_samesite="" session.save_handler="redis" upload_max_filesize="100M"

Web server: nginx/1.28.0 ()

User agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36

Database:

Server Software: Alpine Linux

Server Version: 11.4.8-MariaDB

Server SQL Mode: STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Parameters: v-679f8f6e-3f79-8-glpi-gkAtSqeQA0-1760708100@127.0.0.1:3306/glpi

Host info: 127.0.0.1 via TCP/IP

Requirements:
PHP version (8.3.26) is supported.
OS and PHP are relying on 64 bits integers.
Sessions configuration is OK.
Allocated memory is sufficient.
Following extensions are installed: dom, fileinfo, filter, libxml, simplexml, tokenizer, xmlreader,
xmlwriter.
mysqli extension is installed
curl extension is installed
gd extension is installed
intl extension is installed
mbstring extension is installed
zlib extension is installed
bcmath extension is installed
The constant
SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES is present.
openssl extension is installed
Database engine version (11.4.8) is supported.
The log file has been created successfully.
Write access to
/data/app/_cache has been validated.
Write access to /data/app/_cron has been validated.
Write access to /data/app/_files has been validated.
Write access to /data/app/_graphs has been validated.
Write access to /data/app/_lock has been validated.
Write access to /data/app/_pictures has been validated.
Write access to /data/app/_plugins has been validated.
Write access to /data/app/_rss has been validated.
Write access to /data/sessions has been validated.
Write access to /data/tmp has been validated.
Write access to /data/tmp has been validated.

Sessions configuration is secured.
exif extension is installed
ldap extension is installed
Following extensions are installed: bz2,
Phar, zip.
Zend OPcache extension is installed
Following extensions are installed:
ctype, iconv, sodium.
Write access to
/data/app/marketplace has been validated.
Timezones seems not loaded, see
https://glpi-install.readthedocs.io/en/latest/timezones.html.

GLPI constants
GLPI_ROOT: "/app"
GLPI_VERSION: "11.0.1"
GLPI_SCHEMA_VERSION: "11.0.1@ea2dbba0e1edbf5128d73bdb23c2c9b9f68468ba"
GLPI_FILES_VERSION: "11.0.1-3a9929cf"
GLPI_MIN_PHP: "8.2"
GLPI_MAX_PHP: "8.5"
GLPI_YEAR: "2025"
GLPI_I18N_DIR: "/app/locales"
GLPI_VAR_DIR: "/data/app"
GLPI_MARKETPLACE_DIR: "/data/app/marketplace"
GLPI_DOC_DIR: "/data/app/files"
GLPI_SESSION_DIR: "/data/sessions"
GLPI_TMP_DIR: "/data/tmp"
GLPI_UPLOAD_DIR: "/data/tmp"
GLPI_ENVIRONMENT_TYPE: "production"
GLPI_CONFIG_DIR: "/app/config"
GLPI_ALLOW_IFRAME_IN_RICH_TEXT: false
GLPI_SERVERSIDE_URL_ALLOWLIST: ["~^\n (http|https|feed)://
# protocol\n (\n (?:\n
(?:xn--[a-z0-9-]++\.)*+xn--[a-z0-9-]++ # a domain name using punycode\n
|\n (?:[\pL\pN\pS\pM\-\
]++\.)+[\pL\pN\pM]++ # a multi-level domain
name\n |\n [a-z0-9\-\]++
# a single-level domain name\n )\.?\n |
# or\n \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
# an IP address\n | #
or\n \[\n
(?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))\n
\] # an IPv6 address\n
)\n (?:/ (?:[\pL\pN\pS\pM\-.
\!$&'()+,;=:@]|%[0-9A-Fa-f]{2}) )* # a path\n
(?:\? (?:[\pL\pN\-._\
!$&'\\+,;=:@/?]|%[0-9A-Fa-f]{2}) )? # a query (optional)\n
$~ixuD"]
GLPI_DISALLOWED_UPLOADS_PATTERN: "/\.(php\d*|phar)$/i"
GLPI_TELEMETRY_URI: "https://telemetry.glpi-project.org"
GLPI_INSTALL_MODE: "TARBALL"
GLPI_NETWORK_MAIL: "glpi@teclib.com"
GLPI_NETWORK_SERVICES: "https://services.glpi-network.com"
GLPI_MARKETPLACE_ENABLE: 3
GLPI_MARKETPLACE_PRERELEASES: false
GLPI_MARKETPLACE_ALLOW_OVERRIDE: true
GLPI_MARKETPLACE_MANUAL_DOWNLOADS: true
GLPI_USER_AGENT_EXTRA_COMMENTS: ""
GLPI_DOCUMENTATION_ROOT_URL: "https://links.glpi-project.org"
GLPI_DISABLE_ONLY_FULL_GROUP_BY_SQL_MODE: "1"
GLPI_LOG_LVL: "warning"
GLPI_SKIP_UPDATES: false
GLPI_STRICT_ENV: false
GLPI_AJAX_DASHBOARD: "1"
GLPI_CALDAV_IMPORT_STATE: 0
GLPI_CENTRAL_WARNINGS: "1"
GLPI_SYSTEM_CRON: false
GLPI_TEXT_MAXSIZE: "4000"
GLPI_WEBHOOK_ALLOW_RESPONSE_SAVING: "0"
GLPI_WEBHOOK_CRA_MANDATORY: false
GLPI_ALTCHA_MODE: "interactive"
GLPI_ALTCHA_MAX_NUMBER: 50000
GLPI_ALTCHA_EXPIRATION_INTERVAL: "PT20M"
GLPI_CACHE_DIR: "/data/app/_cache"
GLPI_CRON_DIR: "/data/app/_cron"
GLPI_GRAPH_DIR: "/data/app/_graphs"
GLPI_LOCAL_I18N_DIR: "/data/app/_locales"
GLPI_LOCK_DIR: "/data/app/_lock"
GLPI_LOG_DIR: "/data/app/_log"
GLPI_PICTURE_DIR: "/data/app/_pictures"
GLPI_PLUGIN_DOC_DIR: "/data/app/_plugins"
GLPI_RSS_DIR: "/data/app/_rss"
GLPI_INVENTORY_DIR: "/data/app/_inventories"
GLPI_THEMES_DIR: "/data/app/_themes"
GLPI_PLUGINS_DIRECTORIES: ["/data/app/marketplace","/app/plugins"]
GLPI_NETWORK_REGISTRATION_API_URL: "https://services.glpi-network.com/api/registration/"
GLPI_MARKETPLACE_PLUGINS_API_URI: "https://services.glpi-network.com/api/marketplace/"
Annuaires LDAP
Server: '127.0.0.1',
Port: '389',
BaseDN: 'DC=lapiole,DC=org',
Connection filter:
'(&(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=Role_Support_User,OU=Roles,DC=lapiole,DC=org)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',

RootDN: 'glpi@lapiole.org', 
Use TLS: none

Server: 'office.lapiole.org',
Port: '389',
BaseDN: 'DC=lapiole,DC=org',
Connection filter: '(&(objectClass=inetOrgPerson)(|(posixMemberOf=admins)(posixMemberOf=equipe)))',
RootDN: none,
Use TLS: '1'

Réplicats SQL
Not active
Notifications
Way of sending emails: SMTP(smtp://localhost:25?verify_peer=0)
Name: 'Support (Zimbra)'
Active: Yes
Server: '{127.0.0.1:143/imap/notls}INBOX'
Login: 'glpi@lapiole.org'
Password: Yes
Plugins list
behaviors            Name: Behaviours                     Version: 3.0.1      State: Activé
Install Method: Manual
fields Name: Champs supplémentaires Version: 1.21.22 State: Installé / non activé
Install Method: Manual
pdf Name: Print to pdf Version: 4.1.0 State: Activé
Install Method: Manual
manufacturersimports Name: Suppliers imports Version: 3.1.1 State: Activé
Install Method: Manual
tag Name: Tag Management Version: 2.13.0 State: Activé
Install Method: Manual

Anything else?

I'm using redis for session storage, but I don't think it's related

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions