Aller au contenu

systemd : dépannage

Méthode et erreurs fréquentes pour comprendre pourquoi un service ne démarre pas. Les exemples utilisent des noms génériques.

  1. État : systemctl status nom (résumé et dernières lignes du journal).
  2. Journal complet : journalctl -xeu nom (-x ajoute des explications, -e va à la fin).
  3. Configuration réelle : systemctl cat nom et systemd-analyze verify /etc/systemd/system/nom.service.
  4. Reproduire à la main : lancer la commande de ExecStart avec le même utilisateur.
Fenêtre de terminal
systemctl status monapp --no-pager
journalctl -xeu monapp --no-pager
systemctl cat monapp
systemd-analyze verify /etc/systemd/system/monapp.service
sudo -u monapp /usr/bin/python3 /srv/monapp/app/serveur.py # essai manuel
Champ Valeurs et sens
Loaded: loaded, not-found (fichier absent), masked, bad-setting (erreur de syntaxe)
Active: active (running), active (exited) (tâche terminée avec succès), inactive (dead), failed
Process: … (code=exited, status=203/EXEC) Code de sortie (voir ci-dessous)
Main PID: Processus principal

Le résultat enregistré :

Fenêtre de terminal
systemctl show monapp -p Result,ExecMainStatus,ExecMainCode,NRestarts,ActiveEnterTimestamp --no-pager
Result= Cause
success Terminé normalement
exit-code Sortie avec un code non nul
signal Tué par un signal
timeout Démarrage ou arrêt trop long
start-limit-hit Trop de redémarrages (voir plus bas)
oom-kill Tué faute de mémoire (limite MemoryMax ou mémoire de la machine)

Codes 200 à 243 : l’échec a eu lieu avant le lancement du programme (testés sur systemd 255 et 259).

Code Signification Cause fréquente
200/CHDIR Impossible d’aller dans WorkingDirectory Dossier inexistant ou droits
203/EXEC Impossible d’exécuter ExecStart Chemin faux, fichier non exécutable, mauvais interpréteur (#!)
217/USER Utilisateur introuvable User= mal orthographié, compte absent
216/GROUP Groupe introuvable Group=
226/NAMESPACE Échec de l’isolation Un chemin de ReadWritePaths, BindPaths ou RootDirectory n’existe pas
206/OOM_ADJUST, 205/LIMITS Limites système refusées LimitNOFILE… trop hautes
31/SYS, signal SIGSYS Appel système bloqué SystemCallFilter trop strict
1 à 199 Code renvoyé par le programme lui-même Lire le journal de l’application

La liste complète : man systemd.exec (section PROCESS EXIT CODES).

monapp.service: Start request repeated too quickly.
monapp.service: Failed with result 'start-limit-hit'.

systemd cesse d’essayer après StartLimitBurst démarrages dans StartLimitIntervalSec. Corriger la cause (journal), puis :

Fenêtre de terminal
sudo systemctl reset-failed monapp
sudo systemctl start monapp
Warning: The unit file, source configuration file or drop-ins of monapp.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Fenêtre de terminal
sudo systemctl daemon-reload
sudo systemctl restart monapp

daemon-reload relit les fichiers ; restart applique les nouveaux réglages au processus.

Message Cause et solution
Unit nom.service not found Mauvais nom : systemctl list-unit-files | grep nom ; fichier absent de /etc/systemd/system
Unit … is masked sudo systemctl unmask nom
Failed to enable unit: Unit file … does not exist Créer le fichier ou vérifier le nom
Unknown key name … in section 'Service', ignoring Directive inexistante ou faute de frappe (voir systemd-analyze verify)
Service has no ExecStart=, ExecStop=, or SuccessAction= Section [Service] sans commande
Missing '=' , ignoring line Ligne sans = dans le fichier d’unité
bad-setting Erreur de syntaxe : systemd-analyze verify
Dependency failed for monapp.service.

Une unité requise (Requires=) a échoué : lire systemctl status de cette unité.

Fenêtre de terminal
systemctl list-dependencies monapp --no-pager
systemctl --failed
systemctl list-jobs # tâches en attente (démarrage bloqué ?)

Un service n’hérite pas de l’environnement de la session : PATH minimal, pas de variables HOME, LANG habituelles, pas de répertoire courant.

Fenêtre de terminal
sudo systemd-run --pty --uid=monapp /usr/bin/env # voir l'environnement réel d'un service
systemctl show monapp -p Environment # variables définies dans l'unité

Remèdes : chemins absolus, WorkingDirectory=, Environment= ou EnvironmentFile=. Rappel : la valeur d’EnvironmentFile= l’emporte sur Environment= (voir Écrire un service).

Fenêtre de terminal
namei -l /srv/monapp/app/serveur.py # droits sur chaque dossier du chemin
sudo -u monapp test -r /srv/monapp/app/serveur.py && echo "lisible"
ls -ld /srv/monapp /etc/monapp.env

L’utilisateur du service doit pouvoir traverser (x) chaque dossier du chemin et lire les fichiers ; avec ProtectSystem=strict et ProtectHome, voir Durcissement.

Fenêtre de terminal
systemd-analyze blame --no-pager | head
systemd-analyze critical-chain monapp.service
journalctl -u monapp -b --no-pager | head -30

Un arrêt qui prend 90 secondes (TimeoutStopSec) indique un programme qui n’intercepte pas SIGTERM : régler TimeoutStopSec= plus court, et corriger l’application.

Si la machine ne démarre pas normalement :

  1. Console de l’hébergeur ou écran : choisir le mode de secours (menu GRUB, option « recovery ») ou ajouter systemd.unit=rescue.target à la ligne de démarrage.
  2. Lire les erreurs : journalctl -xb -p err.
  3. Corriger (ligne erronée de /etc/fstab, service défectueux masqué avec systemctl mask).
  4. Redémarrer : systemctl reboot.

Une ligne de /etc/fstab fautive est une cause classique : ajouter nofail aux montages non essentiels.

Symptôme Piste
Failed to connect to bus: No such file or directory (commande --user) Pas de session utilisateur : loginctl enable-linger, ou XDG_RUNTIME_DIR
Access denied Droits insuffisants : utiliser sudo
systemctl: command not found dans un conteneur Le conteneur n’utilise pas systemd comme processus 1
Un timer ne se déclenche pas Voir Timers
Les journaux sont vides Voir Journal (persistance, droits)
Job for nom.service failed because the control process exited with error code systemctl status nom puis journalctl -xeu nom

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Les codes de sortie et les messages de cette page sont identiques sur systemd 255 et 259 (testés). Les liens symboliques créés par enable s’affichent avec des guillemets droits sur 26.04 (Created symlink '…' → '…'), sans conséquence.