Risolvere npm ERR! code EADDRINUSE: Address already in use
Soluzione Rapida
Se conosci il numero di porta che la tua applicazione sta cercando di utilizzare (ad esempio, porta 3000), esegui i seguenti comandi nel terminale per identificare e terminare il processo che la sta occupando.
Linux / macOS (Bash)
# 1. Trova il Process ID (PID) in esecuzione sulla porta 3000
lsof -i :3000
# Output tipico:
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# node 12345 root 22u IPv4 0x12345678 0t0 TCP *:3000 (LISTEN)
# 2. Termina il processo usando il PID trovato (es. 12345)
kill -9 12345
Terminazione rapida in una riga:
# Termina forzatamente qualsiasi processo sulla porta 3000
npx kill-port 3000
Windows (PowerShell)
# 1. Trova il PID in ascolto sulla porta 3000
Get-NetTCPConnection -LocalPort 3000
# 2. Ferma il processo usando il PID (OwningProcess)
Stop-Process -Id <PID> -Force
Perché accade questo errore
L’errore EADDRINUSE è l’acronimo di “Error Address In Use” (Errore Indirizzo In Uso). È un segnale a livello di sistema operativo che indica che un’applicazione sta tentando di associare (bind) un socket TCP/IP a una porta di rete che è già occupata da un altro processo attivo.
Nel contesto di Node.js, questo errore si verifica quasi esclusivamente durante l’inizializzazione del server HTTP (server.listen()). Quando la tua applicazione richiede al kernel di riservare una porta (es. 3000), il sistema controlla la tabella globale dei socket. Se quella combinazione IP:Porta è già assegnata, la richiesta viene respinta con il codice di errore EADDRINUSE.
Cause Comuni
- Processi Zombie: Un’istanza precedente del server Node.js non è stata chiusa correttamente (ad esempio dopo un crash o un
Ctrl+Cnon gestito), lasciando il socket aperto in background. - Esecuzione Multipla: Tentativo di avviare due istanze della stessa applicazione contemporaneamente (es. due terminali aperti sullo stesso progetto).
- Conflitto con Altri Servizi: Un altro servizio (come un database locale, Docker, o un’altra app) sta già utilizzando la porta richiesta.
- Race Condition nei Test: Esecuzione di suite di test in parallelo dove ogni worker tenta di avviare un server sulla stessa porta fissa.
Diagnostica Avanzata su Linux
Su sistemi Linux (Ubuntu, Debian, CentOS, ecc.), esistono strumenti potenti per ispezionare lo stato della rete.
1. Utilizzare lsof (List Open Files)
lsof è lo standard de facto per mappare file e socket ai processi.
# Sintassi: lsof -i :<PORTA>
sudo lsof -i :3000
Se il comando non restituisce nulla ma ricevi comunque l’errore, il processo potrebbe essere stato avviato da un altro utente (o root), motivo per cui sudo è spesso necessario.
2. Utilizzare netstat
Se lsof non è disponibile, netstat è una valida alternativa.
# -n: Indirizzi numerici
# -l: Solo socket in ascolto
# -p: Mostra PID/Nome programma
sudo netstat -nlp | grep :3000
3. Utilizzare fuser
Per identificare e terminare il processo in un colpo solo:
# Visualizza solo il PID
fuser 3000/tcp
# Termina il processo che occupa la porta (k = kill)
fuser -k 3000/tcp
Diagnostica Avanzata su macOS
macOS condivide molti strumenti con Linux ma con alcune differenze nei flag.
1. Utilizzare lsof
Il comando è simile a Linux, ma possiamo essere più specifici con i protocolli.
# Trova processi TCP in stato LISTEN sulla porta 3000
lsof -iTCP:3000 -sTCP:LISTEN
2. Monitoraggio Attività (GUI)
Se preferisci l’interfaccia grafica:
- Apri Monitoraggio Attività (Activity Monitor) tramite Spotlight.
- Vai alla scheda Rete o CPU.
- Cerca “node” nella barra di ricerca.
- Seleziona il processo e clicca sulla “X” in alto per forzare l’uscita.
Diagnostica Avanzata su Windows
Windows gestisce i socket in modo diverso rispetto ai sistemi Unix-like.
1. PowerShell (Metodo Consigliato)
PowerShell offre cmdlet nativi per la gestione della rete, eliminando la necessità di strumenti esterni.
# Ottieni dettagli completi sulla connessione
Get-NetTCPConnection -LocalPort 3000 | Format-List
# Filtra per ottenere solo il PID e lo stato
Get-NetTCPConnection -LocalPort 3000 | Select-Object OwningProcess, State, LocalAddress
2. Prompt dei Comandi (cmd)
Il classico netstat è ancora ampiamente utilizzato.
# -a: Tutte le connessioni
# -n: Numerico
# -o: Mostra PID proprietario
netstat -ano | findstr :3000
Per terminare il processo dal prompt dei comandi:
taskkill /PID <PID> /F
Gestione Programmatica dell’Errore
Invece di lasciare che l’applicazione crashi, puoi gestire l’errore EADDRINUSE nel tuo codice Node.js. Questo è utile per implementare logiche di riprova o fallback.
Esempio: Riprovare su una Porta Diversa
const http = require('http');
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
const startServer = (retryPort) => {
const serverPort = retryPort || port;
server.listen(serverPort, () => {
console.log(`Server in esecuzione su http://localhost:${serverPort}/`);
});
server.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
console.log(`Porta ${serverPort} occupata, riprovo con ${serverPort + 1}...`);
server.close(); // Chiudi il server fallito
startServer(serverPort + 1); // Riprova incrementando la porta
} else {
console.error('Errore del server:', e);
}
});
};
startServer();
Esempio: Usare una Porta Casuale
Se la porta specifica non è importante (es. durante i test), lascia che il sistema operativo ne assegni una libera passando 0.
server.listen(0, () => {
const assignedPort = server.address().port;
console.log(`Server avviato su porta casuale: ${assignedPort}`);
});
Prevenzione e Best Practices
-
Graceful Shutdown: Assicurati che la tua applicazione gestisca i segnali di terminazione (
SIGINT,SIGTERM) per chiudere pulitamente le connessioni e rilasciare la porta.process.on('SIGTERM', () => { server.close(() => { console.log('Processo terminato'); }); }); -
Ambienti di Sviluppo (Nodemon): Se usi
nodemon, assicurati che non lasci processi orfani. A volte, nodemon può riavviare l’app prima che il processo precedente abbia rilasciato completamente la porta. -
Container Docker: Assicurati di mappare correttamente le porte nel
docker-compose.yml. Un erroreEADDRINUSEin Docker spesso significa che stai cercando di mappare più container sulla stessa porta dell’host.ports: - "3000:3000" # Host:ContainerSe hai più servizi, usa porte host diverse (es.
3001:3000).
FAQ - Domande Frequenti
Perché succede ogni volta che salvo un file con nodemon?
Questo accade spesso se l’applicazione non gestisce correttamente il segnale di riavvio inviato da nodemon. Nodemon invia un segnale (default SIGUSR2) per riavviare. Se il tuo codice non chiude il server (server.close()) alla ricezione del segnale, il nuovo processo tenterà di avviarsi mentre il vecchio socket è ancora attivo.
Come posso prevenire questo errore nelle pipeline CI/CD?
Negli ambienti CI (come GitHub Actions o Jenkins), l’hardcoding delle porte (es. 3000) causa spesso conflitti se più job girano sulla stessa macchina. La best practice è utilizzare app.listen(0) per lasciare che il sistema operativo assegni una porta effimera libera, evitando collisioni.
È sicuro usare kill -9 per terminare il processo?
kill -9 invia il segnale SIGKILL, che termina il processo immediatamente senza permettergli di eseguire operazioni di pulizia (come chiudere connessioni al database o scrivere log). Sebbene risolva l’errore EADDRINUSE, dovrebbe essere usato come ultima risorsa. Preferisci prima kill -15 (SIGTERM).
Cosa significa listen EADDRINUSE: address already in use :::3000?
I tre due punti ::: indicano un indirizzo IPv6. Node.js, per default in molte versioni, tenta di ascoltare sia su IPv4 che su IPv6 se non viene specificato un host. Questo errore conferma che la porta 3000 è occupata sull’interfaccia IPv6 (che spesso copre anche IPv4 in modalità dual-stack).
Posso vedere quale applicazione sta usando la porta su Windows senza comandi?
Sì. Puoi aprire “Gestione Risorse” (Resource Monitor), andare alla scheda “Rete” e guardare la sezione “Porte in ascolto” (Listening Ports). Lì troverai l’elenco delle porte e i nomi dei processi associati, permettendoti di identificarli visivamente.
Errori Correlati
- linux-permission-denied: Se ricevi un errore
EACCEStentando di usare porte inferiori alla 1024 senza permessi di root. - npm ERR! code ELIFECYCLE: Spesso accompagna EADDRINUSE quando lo script di avvio fallisce ed esce in modo anomalo.
- ECONNREFUSED: L’opposto di EADDRINUSE; indica che nessuno sta ascoltando sulla porta a cui stai provando a connetterti.