MWCodebymw.de ↗
Terminal

„Address already in use" – herausfinden, wer den Port belegt

Der Entwicklungsserver startet nicht, weil Port 8000 angeblich schon benutzt wird – meistens von einem eigenen Prozess von vorhin. Mit ss oder lsof findest du ihn in Sekunden, statt das Terminal neu zu starten.

Man kennt die Meldung:

Failed to listen on 0.0.0.0:8000 (reason: Address already in use)

Fast immer ist es ein eigener Prozess von vorhin, der im Hintergrund weiterläuft. Die üblichen Reaktionen — Terminal neu starten, Rechner neu starten, einen anderen Port nehmen — funktionieren, sind aber unnötig.

Wer hört auf dem Port? (Linux)

ss -tulpn | grep :8000

Die Buchstaben stehen für: tcp, udp, listening, process, numerisch (also Portnummern statt Dienstnamen). Die Ausgabe endet mit etwas wie:

users:(("php",pid=3831,fd=4))

Da steht alles Nötige: Programm und Prozess-ID.

Oder mit lsof (Linux und macOS)

lsof -i :8000

lsof gibt es auf beiden Systemen und die Ausgabe ist etwas leserlicher — dafür ist es oft nicht vorinstalliert. Auf macOS ist es der übliche Weg, weil ss dort fehlt.

Wenn du nur die PID willst:

lsof -ti :8000        # gibt ausschließlich die Prozess-ID aus

Beenden

kill 3831             # höflich: bitte aufräumen und beenden
kill -9 3831          # notfalls: sofort abschießen

Zuerst immer das normale kill. Damit bekommt der Prozess die Chance, Dateien zu schließen und aufzuräumen. -9 lässt ihm keine — bei einem Entwicklungsserver egal, bei einer Datenbank keine gute Idee.

In einem Rutsch:

kill "$(lsof -ti :8000)"

Das nehme ich nur, wenn ich vorher gesehen habe, was dort läuft. Blind alles zu beenden, was auf einem Port lauscht, ist genau die Sorte Einzeiler, die man irgendwann versehentlich auf dem falschen Rechner ausführt.

Und wenn gar kein Prozess auftaucht?

Dann gibt es zwei häufige Erklärungen:

  • Der Prozess gehört einem anderen Nutzer. ss und lsof zeigen fremde Prozesse nur mit erhöhten Rechten — probier es mit sudo.
  • Der Port hängt im Zustand TIME_WAIT. Nach dem Beenden eines Servers bleibt die Verbindung noch kurz reserviert, damit verspätete Pakete nicht in eine neue Verbindung platzen. Das löst sich nach ein paar Sekunden bis zwei Minuten von selbst. Sichtbar wird es mit:
ss -tan | grep :8000

Was ich mir angewöhnt habe

Entwicklungsserver starte ich in einem eigenen Terminal und beende sie dort auch wieder, statt sie in den Hintergrund zu schicken und zu vergessen. Wenn ich sie doch im Hintergrund brauche, schreibe ich die PID in eine Datei:

php -S 127.0.0.1:8000 & echo $! > .server.pid
kill "$(cat .server.pid)" && rm .server.pid

Dann muss man nie suchen. Aber wenn doch: ss -tulpn | grep :PORT ist der Befehl, den ich am häufigsten aus meinem Verlauf hole.

Du kämpfst öfter mit einer lokalen Entwicklungsumgebung, die nicht so will? Manchmal ist es eine Kleinigkeit, manchmal die Einrichtung. Frag mich.

Quellen

#Terminal#Prozesse#Ports#ss#lsof

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →