Introduction
Systemd est puissant, mais ses messages d'erreur peuvent sembler obscurs lorsqu'une unité ne démarre pas ou redémarre en boucle. Ce guide se concentre sur les erreurs systemd les plus fréquentes en pratique, explique pourquoi elles se produisent, comment les diagnostiquer rapidement et les corriger en toute sécurité.
Vous obtiendrez :
- Un flux de travail de dépannage répétable
- Une aide-mémoire des commandes d'inspection
- Erreurs pratiques, causes racines et correctifs prêts à l'emploi
- Un plan de pilote local pour vous exercer sans risque avant la production
Vue d'ensemble du flux de travail de dépannage
Utilisez cette séquence de bout en bout. Elle est rapide, sûre et répétable.
- Identifier l'unité et reproduire en sécurité
- Connaître le nom exact de l'unité (ex.
nginx.service). Évitez les suppositions. - Si possible, reproduisez d'abord dans un environnement non productif.
- Inspecter l'état en premier
systemctl status nginx.service --no-pager -l
Recherchez : état actif, ExecStart, PID principal, code/statut, dernières lignes de journal.
- Lire les journaux avec contexte
journalctl -xeu nginx.service --no-pager
# Ou restreindre au démarrage actuel
journalctl -u nginx.service -b --no-pager
- Vérifier la syntaxe de l'unité et voir le fichier chargé par systemd
systemctl cat nginx.service
systemctl show nginx.service -p FragmentPath -p DropInPaths
systemd-analyze verify /etc/systemd/system/nginx.service
- Tester la commande en dehors de systemd
- Exécutez la commande ExecStart manuellement en tant qu'utilisateur du service si applicable.
- Exemple :
sudo -u nginx /usr/sbin/nginx -tpour tester la configuration nginx. - Vérifiez les permissions et l'existence des binaires et scripts.
- Pour les scripts, confirmez le bit d'exécution et le shebang correct.
- Vérifier l'ordre et les dépendances
systemctl list-dependencies --reverse nginx.service
systemd-analyze critical-chain nginx.service
Ajustez Wants=, Requires= et After= selon les besoins. La sortie critical-chain montre quelles unités retardent le démarrage.
- Examiner le bac à sable (sandboxing) et les systèmes de fichiers
- Des options comme
ProtectSystem,ReadWritePaths,PrivateTmp,DynamicUseretWorkingDirectorypeuvent bloquer les écritures ou l'accès. - Si les écritures échouent, soit assouplissez les protections, soit écrivez dans les chemins autorisés comme
RuntimeDirectory.
- Appliquer les modifications en toute sécurité et recharger
systemctl daemon-reload
systemctl restart nginx.service
Préférez l'utilisation de drop-ins via :
systemctl edit nginx.service
Cela crée /etc/systemd/system/nginx.service.d/override.conf.
- Confirmer et surveiller
systemctl is-active nginx.service && echo OK
journalctl -u nginx.service -b -n 50 --no-pager
Aide-mémoire des diagnostics
- État et derniers journaux
systemctl status <unité> --no-pager -l
journalctl -xeu <unité> --no-pager
- Afficher l'unité chargée et les drop-ins
systemctl cat <unité>
systemctl show <unité> -p FragmentPath -p DropInPaths
- Valider la syntaxe de l'unité
systemd-analyze verify /etc/systemd/system/<unité>
- Journaux limités au démarrage actuel
journalctl -u <unité> -b --no-pager
- Dépendances et chaîne critique
systemctl list-dependencies --reverse <unité>
systemd-analyze critical-chain <unité>
- Environnement
systemctl show <unité> -p Environment -p EnvironmentFiles
Erreurs courantes et correctifs
Voici les erreurs que vous rencontrerez probablement, avec leurs causes, diagnostics et correctifs sûrs.
1) "Unit <name>.service not found"
Symptôme :
systemctl start myapp
Failed to start myapp.service: Unit myapp.service not found.
Pourquoi ça arrive :
- Le fichier d'unité est absent ou mal nommé.
- Vous avez créé ou modifié une unité sans exécuter
daemon-reload.
Diagnostiquer :
ls /etc/systemd/system/myapp.service /lib/systemd/system/myapp.service
systemctl daemon-reload && systemctl list-unit-files | grep myapp
Corriger :
- Assurez-vous que le fichier est placé à
/etc/systemd/system/myapp.service. - Corrigez le nom et l'extension de l'unité.
- Rechargez et démarrez :
systemctl daemon-reload
systemctl enable --now myapp.service
2) "Unit is masked"
Symptôme :
systemctl start docker
Failed to start docker.service: Unit docker.service is masked.
Pourquoi ça arrive :
- L'unité est liée à
/dev/nullpour empêcher son activation.
Diagnostiquer :
ls -l /etc/systemd/system/docker.service
systemctl status docker
Corriger (comprenez d'abord pourquoi elle était masquée) :
systemctl unmask docker.service
systemctl enable --now docker.service
3) "Failed at step EXEC spawning ...: No such file or directory"
Symptôme :
systemd[1]: myapp.service: Failed at step EXEC spawning /usr/local/bin/myapp: No such file or directory
Pourquoi ça arrive :
- Le chemin ExecStart est erroné ou manquant.
- Le script a un shebang avec un chemin d'interpréteur invalide.
Diagnostiquer :
file /usr/local/bin/myapp
head -n1 /usr/local/bin/myapp
which myapp
Corriger :
- Pointez ExecStart vers le chemin absolu correct.
- Pour les scripts, utilisez un shebang valide comme :
#!/usr/bin/env bash
- Assurez-vous du bit d'exécution :
chmod +x /usr/local/bin/myapp
4) "Exec format error" ou permission refusée pour les scripts
Symptôme :
... myapp.sh: Exec format error
Pourquoi ça arrive :
- Fins de ligne Windows (CRLF).
- Pas exécutable ou interpréteur manquant.
Diagnostiquer et corriger :
file myapp.sh # affiche CRLF si présent
sed -i 's/
$//' myapp.sh # convertir en LF
chmod +x myapp.sh
head -n1 myapp.sh # confirmer le shebang
5) "Start request repeated too quickly" (boucle de plantage)
Symptôme :
systemd[1]: myapp.service: Start request repeated too quickly.
Pourquoi ça arrive :
- Le service se termine rapidement, souvent avec
Restart=always.
Diagnostiquer :
journalctl -u myapp -b -n 100 --no-pager
systemctl show myapp -p Restart -p StartLimitBurst -p StartLimitIntervalSec
Corriger :
- Corrigez d'abord le plantage sous-jacent (mauvaise config, variable d'environnement manquante, mauvais chemin).
- Optionnellement, assouplissez les limites pendant le débogage :
[Unit]
StartLimitIntervalSec=60
StartLimitBurst=10
[Service]
Restart=on-failure
RestartSec=2s
Appliquez via :
systemctl edit myapp.service
systemctl daemon-reload && systemctl restart myapp
6) "Dependency failed" ou problèmes d'ordre
Symptôme :
systemd[1]: Dependency failed for myapp.service
Pourquoi ça arrive :
- L'unité requiert une autre unité qui est inactive.
- Le réseau n'est pas prêt mais le service l'attend.
Diagnostiquer :
systemctl list-dependencies --reverse myapp.service
systemd-analyze critical-chain myapp.service
Corriger (exemple : attendre le réseau) :
[Unit]
Wants=network-online.target
After=network-online.target
Sur les systèmes utilisant systemd-networkd, activez aussi :
systemctl enable --now systemd-networkd-wait-online.service
7) EnvironmentFile introuvable
Symptôme :
... Failed to load environment files: No such file or directory
Pourquoi ça arrive :
- Le chemin EnvironmentFile est erroné ou le fichier manque.
Diagnostiquer :
systemctl show myapp -p EnvironmentFiles
ls -l /etc/default/myapp.env
Corriger :
- Créez le fichier et sécurisez les permissions :
install -m 0640 -o root -g root /dev/null /etc/default/myapp.env
echo 'MYAPP_PORT=8080' | tee -a /etc/default/myapp.env >/dev/null
- Dans l'unité :
[Service]
EnvironmentFile=/etc/default/myapp.env
- Rechargez et redémarrez.
8) WorkingDirectory inexistant
Symptôme :
... myapp.service: WorkingDirectory=/opt/myapp: No such file or directory
Pourquoi ça arrive :
- Le répertoire est absent ou appartient au mauvais utilisateur.
Corriger :
install -d -o myuser -g myuser /opt/myapp
Ou utilisez RuntimeDirectory pour les chemins éphémères :
[Service]
RuntimeDirectory=myapp
WorkingDirectory=/run/myapp
9) Permission refusée à cause des options de durcissement
Symptôme :
... myapp: permission denied writing /var/log/myapp/output.log
Pourquoi ça arrive :
ProtectSystem=strictou similaire empêche les écritures.
Diagnostiquer :
systemctl cat myapp | sed -n '/\[Service\]/,$p'
Corriger proprement :
- Préférez écrire dans un RuntimeDirectory et laissez systemd le gérer :
[Service]
RuntimeDirectory=myapp
# l'application écrit dans /run/myapp/
- Ou autorisez des chemins d'écriture spécifiques :
[Service]
ProtectSystem=strict
ReadWritePaths=/var/log/myapp
10) Champs d'unité invalides ou fautes de frappe
Symptôme :
... Failed to parse service type, ignoring: simple2
Pourquoi ça arrive :
- Fautes de frappe dans des champs comme Type, ExecStart ou noms de sections.
Corriger :
- Comparez avec la documentation systemd.unit et systemd.service.
- Validez :
systemd-analyze verify /etc/systemd/system/myapp.service
11) "Failed to connect to bus: No such file or directory" dans les conteneurs
Symptôme :
systemctl status
Failed to connect to bus: No such file or directory
Pourquoi ça arrive :
- La plupart des conteneurs n'exécutent pas systemd comme PID 1.
Correction et conseil :
- Ne comptez pas sur systemctl dans les conteneurs simples. Exécutez votre processus au premier plan et gérez-le avec le runtime de conteneur.
- Si vous avez vraiment besoin de systemd dans un conteneur, utilisez une image de base conçue pour cela et démarrez le conteneur avec les paramètres init appropriés. Évaluez la sécurité et la complexité avant de procéder.
Plan de pilote local
Commencez petit, mesurable et facile à inspecter localement.
Objectif : Monter un service minimal, déclencher deux erreurs courantes et les corriger.
- Créer un service simple
cat >/usr/local/bin/hello.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
: "${HELLO_MSG:=Hello}"
echo "$(date -Is) $HELLO_MSG" | tee -a /var/log/hello/hello.log
sleep 2
EOF
chmod +x /usr/local/bin/hello.sh
install -d -m 0755 /var/log/hello
cat >/etc/systemd/system/hello.service <<'EOF'
[Unit]
Description=Hello demo service
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
EnvironmentFile=-/etc/default/hello
ExecStart=/usr/local/bin/hello.sh
Restart=on-failure
RestartSec=1s
# Durcir tout en autorisant l'écriture des logs
ProtectSystem=strict
ReadWritePaths=/var/log/hello
[Install]
WantedBy=multi-user.target
EOF
install -m 0644 /dev/null /etc/default/hello
printf 'HELLO_MSG=Hello from systemd\n' >> /etc/default/hello
systemctl daemon-reload
systemctl enable --now hello.service
systemctl status hello --no-pager -l
journalctl -u hello -b -n 50 --no-pager
- Vérification du pilote : valider le comportement
- Attendez-vous à ce que le service démarre et écrive dans
/var/log/hello/hello.log. - Confirmez avec :
tail -n 5 /var/log/hello/hello.log
- Introduire l'erreur A : mauvais chemin ExecStart
systemctl stop hello
systemctl edit hello.service
Ajoutez dans le drop-in :
[Service]
ExecStart=
ExecStart=/usr/local/bin/hello-typo.sh
Puis :
systemctl daemon-reload
systemctl start hello
systemctl status hello -l --no-pager
Observez : Failed at step EXEC spawning ... No such file or directory.
Corriger A :
systemctl edit hello.service
Remplacez par :
[Service]
ExecStart=
ExecStart=/usr/local/bin/hello.sh
Rechargez et redémarrez.
- Introduire l'erreur B : boucle de plantage
sed -i '1i exit 1' /usr/local/bin/hello.sh # forcer l'échec au début
systemctl restart hello
journalctl -xeu hello --no-pager
Observez : Start request repeated too quickly si ça plante vite.
Corriger B :
- Retirez le exit injecté :
sed -i '1d' /usr/local/bin/hello.sh
- Optionnellement, ajustez les limites pendant les tests :
systemctl edit hello.service
Ajoutez :
[Unit]
StartLimitIntervalSec=60
StartLimitBurst=10
Rechargez et redémarrez.
- Inspecter et nettoyer
journalctl -u hello -b --no-pager
systemctl disable --now hello
rm -f /etc/systemd/system/hello.service
systemctl daemon-reload
Pourquoi ce pilote fonctionne :
- Il est ciblé et mesurable : démarrage, écriture de log, deux échecs induits, deux correctifs.
- Il est facile à inspecter localement sans effets de bord.
Conclusion
Quand systemd échoue, suivez un flux de travail cohérent : inspectez l'état, lisez les journaux, vérifiez l'unité, testez la commande manuellement, contrôlez les dépendances et le durcissement, puis appliquez les modifications en toute sécurité et rechargez. Gardez une aide-mémoire des commandes à portée de main et entraînez-vous avec un petit pilote local pour reconnaître les schémas rapidement. Avec ces étapes et exemples, vous transformerez des messages confus en causes racines claires et en correctifs sûrs et confiants.