✦ Oplossingen · Server- en developerfouten

Error: listen EADDRINUSE: address already in use :::3000

‘listen EADDRINUSE: address already in use :::3000’ in Node.js? Een ander proces bezet de poort. Zo vind en stop je het op Linux, macOS en Windows.

Zo ziet de foutmelding eruit

  • Error: listen EADDRINUSE: address already in use :::3000
  • Error: listen EADDRINUSE: address already in use 127.0.0.1:3000
  • code: 'EADDRINUSE'
  • EADDRINUSE

Waarom gebeurt dit?

Een programma dat als server werkt, zoals een Node.js-app, een ontwikkelserver of een API, moet een poort openen om verbindingen te ontvangen. Op één adres kan maar één proces tegelijk op een poort luisteren. EADDRINUSE betekent: deze poort is al bezet. In :::3000 staat :: voor ‘alle adressen’ (IPv6, en meestal ook IPv4), en 3000 is de poort.

Meestal is dat bezette proces gewoon een oudere versie van je eigen app: een terminal die nog openstaat, een server die bij het afsluiten niet echt is gestopt, of een proces dat op de achtergrond is blijven hangen. Ook komt het voor dat twee hulpmiddelen dezelfde app starten, bijvoorbeeld nodemon én een procesmanager als PM2, of dat een Docker-container dezelfde poort naar buiten zet.

Soms zit de fout in de code zelf: de app roept listen() twee keer aan, bijvoorbeeld in zowel app.js als server.js, of tijdens tests die de server meermaals starten.

Zo herken je dit probleem

  • De fout verschijnt direct bij het starten, nog voordat de app een aanvraag heeft verwerkt.
  • Na het sluiten van alle terminals of een herstart van de computer is de fout weg: dan was het een achtergebleven proces.
  • Zie je listen EACCES: permission denied, dan is de poort niet bezet maar mag je hem niet openen (bijvoorbeeld een poort onder 1024 zonder rechten).
  • Kan de browser de app niet bereiken terwijl hij wel draait, dan is het eerder ERR_CONNECTION_REFUSED.

Zo los je het op, stap voor stap

Menunamen kunnen per versie of toestel iets anders heten. Loop de stappen op volgorde af en stop zodra het werkt.

  1. Stop de oude versie in je terminals

    Kijk of de app nog in een andere terminal of een ander editorvenster draait en stop hem daar met Ctrl + C. Sluit je een terminalvenster zonder de app te stoppen, dan blijft het proces soms op de achtergrond doorlopen.

  2. Zoek welk proces de poort gebruikt (Linux en macOS)

    Met lsof of ss zie je welk proces op de poort luistert, met het procesnummer (PID). Kijk of het je eigen app is of iets anders. Op een server heb je vaak sudo nodig om processen van andere gebruikers te zien.

    lsof -i :3000
    sudo lsof -iTCP:3000 -sTCP:LISTEN
    sudo ss -ltnp | grep 3000
  3. Stop het proces

    Stop het proces met kill en het PID. Dat vraagt het netjes te stoppen. Reageert het niet, dan dwingt kill -9 het af; gebruik dat als laatste stap, want het proces krijgt dan geen kans om af te ronden.

    kill 12345
    # alleen als het niet stopt:
    kill -9 12345
  4. Zoek en stop het proces op Windows

    In de opdrachtprompt of PowerShell zoek je met netstat de regel met de poort; het laatste getal is het PID. Met taskkill stop je dat proces. In Taakbeheer kun je het PID ook opzoeken op het tabblad Details.

    netstat -ano | findstr :3000
    taskkill /PID 12345 /F
  5. Controleer nodemon, PM2 en Docker

    Draait de app al onder PM2 of als dienst, en start je hem daarnaast met npm run dev of nodemon, dan botsen ze. Kijk wat er al draait en stop de dubbele variant. Een container die dezelfde poort publiceert zie je met docker ps.

    pm2 list
    pm2 stop naam-van-de-app
    docker ps --format '{{.Names}}  {{.Ports}}'
  6. Maak de poort instelbaar

    Laat de app de poort uit een omgevingsvariabele lezen, met een standaardwaarde. Dan kun je hem bij een botsing tijdelijk op een andere poort starten, en kunnen hostingomgevingen hun eigen poort meegeven. In recente macOS-versies gebruikt de AirPlay-ontvanger poort 5000 en 7000; kies voor ontwikkeling dan een andere poort of zet die functie uit.

    // server.js
    const port = process.env.PORT || 3000;
    app.listen(port, () => console.log(`Luistert op poort ${port}`));
    
    # starten op een andere poort (Linux/macOS)
    PORT=3001 npm start
  7. Controleer of listen() maar één keer wordt aangeroepen

    Zoek in je project naar listen(. Exporteer in een Express-app bij voorkeur de app zonder te luisteren, en roep listen() aan in één startbestand. Testbibliotheken kunnen de app dan zonder vaste poort gebruiken.

    grep -rn "listen(" --include=*.js --exclude-dir=node_modules .
  8. Sluit de server netjes af

    Vang stopsignalen af en sluit de server, zodat de poort vrijkomt en lopende verzoeken worden afgerond. Dat voorkomt achtergebleven processen bij herstarten door nodemon, PM2 of systemd.

    const server = app.listen(port);
    
    function stop() {
      server.close(() => process.exit(0));
    }
    process.on('SIGTERM', stop);
    process.on('SIGINT', stop);

Let op: Stop op een server niet blind het proces dat de poort gebruikt. Het kan een andere website, database of dienst zijn. Controleer eerst met lsof of ss welk programma het is.

Wanneer schakel je hulp in?

  • De poort wordt steeds opnieuw bezet door een proces waarvan je niet weet waar het vandaan komt.
  • Je app draait onder PM2, systemd of Docker en na een deploy start hij niet meer op.
  • Je wilt een Node.js-app goed als dienst laten draaien, met herstart en nette shutdown.
  • Op de server botst je app met een andere website of dienst die dezelfde poort wil.

Lukt het niet? Wij helpen

Kom je er met deze stappen niet uit, of wil je het liever niet zelf doen? We kijken online mee of komen langs. Hulp op afstand kost €20 per uur; komen we langs, dan is de prijs op aanvraag. Je weet vooraf waar je aan toe bent.

Aanvraag

Hulp aanvragen

Schrijf kort wat er misgaat en wat je al hebt geprobeerd. Kies of we bellen, online meekijken of langskomen.

Veelgestelde vragen

Vragen over dit probleem

Wat betekent EADDRINUSE?

Een ander proces luistert al op de poort die je app wil gebruiken. Zoek het proces met lsof -i :3000 of netstat -ano en stop het, of gebruik een andere poort.

Hoe stop ik het proces op poort 3000 op Windows?

Zoek het PID met netstat -ano | findstr :3000 en stop het met taskkill /PID <pid> /F.

Waarom blijft de poort bezet nadat ik de terminal sloot?

Het proces is dan op de achtergrond doorgegaan. Stop het via het PID, en zorg dat je app stopsignalen afvangt en de server netjes sluit.

Kan ik gewoon een andere poort kiezen?

Ja, voor ontwikkeling is dat prima, bijvoorbeeld met PORT=3001. Op een server moet de poort wel overeenkomen met de configuratie van de webserver of proxy ervoor.