Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

OSError: [Errno 98] Address already in use in Python

Verified FixPython 3.10+Python NativeSilo: environment

Quick Fix / Solution Rapide

This error occurs when binding to a port that is already in use. Terminate the blocking process with lsof -i : or bind to a different available port.

Root Cause Analysis

This error occurs when Python tries to bind a network socket or web server (such as FastAPI, Flask, or Uvicorn) to a specific TCP port and network interface, but that port is already bound and occupied by another active process.

Cause 1: Orphaned Zombie Server Processes

Stopping a development server with Ctrl+Z (suspending) instead of Ctrl+C (terminating) leaves the server running in the background. Relaunching the script fails because port 8000 remains occupied.

Cause 2: Sockets in TIME_WAIT State

When a server closes without the SO_REUSEADDR socket option, the operating system kernel keeps the TCP socket in TIME_WAIT for 1-2 minutes to ensure lingering packets dissipate.

Cause 3: Port Collisions Between Simultaneous Services

Attempting to launch two microservices (e.g. Django and FastAPI) on the same default port (e.g. 8000 or 5000) causes the second process to raise OSError: [Errno 98] Address already in use (or [Errno 10048] Only one usage of each socket address on Windows).

Reproduction Code (MCVE)

Example: Bug Reproduction
import socket
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind(('127.0.0.1', 54321))
s1.listen(1)
# Binding a second socket to the same address and port raises OSError
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.bind(('127.0.0.1', 54321))

Solution 1: Enable the SO_REUSEADDR Socket Option

Configure socket.SO_REUSEADDR before binding so the operating system permits immediate port reuse after server restarts.

Example: Recommended Solution
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Enable port reuse flag
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 0))  # Port 0 assigns an available port
port = s.getsockname()[1]
print(f'Socket bound successfully on port: {port}')
s.close()

Solution 2: Inspect and Terminate the Conflicting Process via CLI

Identify the process occupying the target port using OS diagnostic utilities and terminate it gracefully.

Example: Alternative Solution
import sys
# Diagnostic commands for developers:
# Linux/macOS: lsof -i :8000 -> kill -9 <PID>
# Windows:     netstat -ano | findstr :8000 -> taskkill /PID <PID> /F
print('Port diagnostic verified.')

Common Mistakes & Edge Cases

1. Windows Errno 10048 vs Linux Errno 98

  • Linux / macOS: OSError: [Errno 98] Address already in use
  • Windows: OSError: [WinError 10048] Only one usage of each socket address is normally permitted

2. Dynamic Port Binding with Port 0

In unit test suites that spin up temporary web servers, pass port=0 to let the operating system assign an available ephemeral port, eliminating test concurrency collisions.

3. Contrasting OSError vs ConnectionRefusedError

OSError [Errno 98] occurs on the server side when binding to a busy port. ConnectionRefusedError occurs on the client side when trying to connect to a port where no server is listening.

4. Note de Reproductibilité Environnementale

Le comportement des commandes système et des résolutions de paquets dépend fortement de votre système d'exploitation (Windows, macOS, Linux), de l'architecture processeur (x86_64 vs ARM64) et de la configuration des permissions locales. Adaptez les chemins et les permissions selon votre environnement d'exécution spécifique.