154 29/03/2026 07/04/2026 6 min

Perché un servizio si riavvia da solo

Quando un servizio parte correttamente ma poi si ferma e viene riavviato in automatico, il problema di solito non è “il servizio in sé”, ma il motivo per cui il sistema o il manager del servizio lo sta facendo cadere e ripartire. Le cause più comuni sono un crash dell’applicazione, un controllo di salute che fallisce, un watchdog esterno, limiti di memoria o file descriptor superati, dipendenze non disponibili oppure una configurazione che manda il processo in loop.

La differenza rispetto a un servizio che “non parte” è importante: qui il demone riesce ad avviarsi, quindi il punto giusto da osservare è cosa succede subito dopo l’avvio, non solo il comando di start.

Diagnosi probabile

Le ipotesi più frequenti, in ordine pratico, sono queste:

  1. Crash dell’applicazione dopo il bootstrap, spesso per errori di configurazione, connessione a database, file mancanti o variabili d’ambiente errate.
  2. Restart policy del service manager troppo aggressiva, che riavvia il processo appena esce con codice non zero.
  3. OOM killer o limiti di memoria: il kernel termina il processo e il manager lo riavvia.
  4. Watchdog esterno o health check che decide che il servizio è degradato e forza il restart.
  5. Dipendenza non pronta, per esempio database, socket, mount o rete, con effetto a catena sul processo principale.
Il primo obiettivo non è “fermare i riavvii”, ma capire se il servizio sta crashando, venendo ucciso, o se è il sistema a spingerlo in restart.

Verifiche immediate

  1. Controlla lo stato del servizio e il motivo dell’ultimo stop. Su sistemi con systemd, il comando più utile è:
    systemctl status NOME_SERVIZIO --no-pager

    Esito atteso: trovi il codice di uscita, l’ora dell’ultimo restart e spesso una riga con l’errore immediatamente precedente al riavvio.

  2. Leggi i log recenti del servizio:
    journalctl -u NOME_SERVIZIO -n 100 --no-pager

    Esito atteso: individui un errore ripetuto, come connessione negata, file non trovato, segnale di terminazione o eccezione dell’applicazione.

  3. Verifica se il kernel ha ucciso il processo per memoria:
    journalctl -k -n 100 --no-pager | grep -iE 'oom|killed process|out of memory'

    Esito atteso: se compare il nome del processo, il riavvio è molto probabilmente dovuto a pressione memoria.

  4. Controlla i restart recenti, utile per capire se c’è un loop:
    systemctl show NOME_SERVIZIO -p NRestarts,ExecMainCode,ExecMainStatus,Restart,RestartUSec

    Esito atteso: un numero alto di restart in poco tempo conferma il comportamento ciclico.

Soluzione consigliata passo-passo

  1. Isola la causa prima di toccare la policy di restart. Se il servizio è in produzione, evita di disabilitare subito il riavvio automatico: rischi di trasformare un crash loop in un down permanente. Prima identifica l’errore preciso nei log e verifica se è riproducibile manualmente.
  2. Se il log indica un problema di configurazione, correggi solo l’elemento segnalato. Esempi tipici: credenziali errate, path sbagliati, porta già occupata, file di certificato mancante, permessi insufficienti, variabile d’ambiente non valorizzata. Dopo la correzione, ricarica il servizio e verifica che non riparta più in loop:
    systemctl restart NOME_SERVIZIO

    Controllo successivo: systemctl status NOME_SERVIZIO --no-pager deve mostrare active (running) senza restart continui.

  3. Se sospetti un problema di dipendenze, verifica il servizio collegato prima del restart. Per esempio database, cache, storage o rete. Se il demone parte prima della dipendenza, valuta un ordine di avvio più corretto o una dipendenza esplicita nel file unit di systemd. Backup del file prima di modificarlo, ad esempio /etc/systemd/system/NOME_SERVIZIO.service:
    cp /etc/systemd/system/NOME_SERVIZIO.service /etc/systemd/system/NOME_SERVIZIO.service.bak

    Poi aggiungi solo se necessario direttive come After= e Requires=, quindi esegui systemctl daemon-reload e un nuovo restart.

  4. Se compare OOM o limiti di risorse, non aumentare subito la memoria senza verifica. Prima controlla consumo reale, log e limiti del servizio. Se serve, alza in modo conservativo i limiti di systemd nel file unit con backup preventivo, ad esempio MemoryMax o LimitNOFILE, solo dopo aver confermato che il processo non è semplicemente difettoso. Controllo successivo: nessun nuovo evento OOM nei log kernel e stabilità del processo per alcuni minuti.
  5. Se il servizio è in crash loop per un bug applicativo, applica un workaround minimo e reversibile: disattiva temporaneamente il restart aggressivo solo se serve a fermare l’effetto a catena e raccogliere evidenze. Nel file unit, dopo backup, puoi passare da restart immediato a un comportamento meno aggressivo, ma solo come misura temporanea. Il fix vero resta la correzione del bug o della configurazione che causa l’uscita del processo.

Esempio pratico di lettura rapida

Se il comando systemctl status mostra un servizio che passa da active a failed in pochi secondi e il journal riporta una riga come “connection refused to database” o “cannot open file”, hai già quasi la diagnosi: il processo si avvia, prova a inizializzarsi e si chiude perché non trova una risorsa essenziale. Se invece nei log compare solo “Killed” o trovi eventi OOM nel kernel, il colpevole è la pressione memoria, non l’applicazione in senso stretto.

Un altro caso frequente è il timeout di startup: il servizio non è davvero guasto, ma impiega più tempo del previsto e il manager lo considera fallito. In quel caso il fix può essere aumentare il timeout di avvio, ma solo dopo aver verificato che il ritardo sia stabile e legittimo, non un sintomo di un problema più serio.

Controlli finali / rollback

  1. Verifica stabilità: dopo il fix, controlla il servizio per almeno 5-10 minuti con systemctl status NOME_SERVIZIO --no-pager e con i log recenti. Esito atteso: nessun nuovo restart e nessun errore ripetuto.
  2. Conferma il comportamento su rete o funzionalità applicativa: se il servizio espone una porta o una web app, prova la connessione reale e non solo lo stato interno. Il servizio deve rispondere in modo coerente con il suo ruolo.
  3. Rollback: se una modifica al file unit o alla configurazione peggiora la situazione, ripristina il backup creato prima dell’intervento e ricarica systemd con systemctl daemon-reload, poi riavvia il servizio. Condizione di successo: il comportamento torna allo stato precedente all’ultima modifica.

Assunzione operativa: i comandi sopra sono pensati per un server Linux con systemd; su altri init system la logica resta la stessa, ma cambiano i comandi di stato e log.