This error occurs when Docker cannot bind a container port to your host machine because the port is already in use by another process or blocked by the operating system.
When you run a Docker container with port mapping (e.g., `-p 80:80` or in docker-compose.yml), Docker attempts to bind the specified host port to the container port. This error appears when that binding fails. The "Ports are not available" error typically means: - Another application or service is already using that port on your host machine - A previous Docker container that didn't shut down cleanly is still holding the port - On Windows, the WinNAT service or Hyper-V has reserved the port range - On macOS Monterey+, system services like AirPlay Receiver may occupy common ports The error message format usually looks like: "Ports are not available: exposing port TCP 0.0.0.0:PORT -> 0.0.0.0:0: listen tcp 0.0.0.0:PORT: bind: address already in use" or on Windows it may show "An attempt was made to access a socket in a way forbidden by its access permissions."
First, find out which process is occupying the port you need:
On Linux/macOS:
# Check what's using port 80
sudo lsof -i :80
# Alternative using netstat
sudo netstat -tlnp | grep :80On Windows (PowerShell as Administrator):
# Find process using port 80
netstat -ano | findstr :80
# Get process name from PID
Get-Process -Id <PID>Note the process name and PID. If it's a service you don't need, you can stop it.
Once you've identified the process, stop it:
On Linux:
# Kill by PID
sudo kill -9 <PID>
# Or stop common services
sudo systemctl stop apache2
sudo systemctl stop nginxOn macOS:
# Kill by PID
sudo kill -9 <PID>
# Stop Apache if running
sudo apachectl stopOn Windows (PowerShell as Administrator):
# Kill by PID
Stop-Process -Id <PID> -Force
# Or stop IIS
Stop-Service W3SVCA previous container might still be holding the port:
# List all containers including stopped ones
docker ps -a
# Remove stopped containers
docker container prune
# Or remove a specific container
docker rm <container_id>
# Force remove if it's stuck
docker rm -f <container_id>If using docker-compose:
# Stop and remove containers
docker-compose down
# Then start fresh
docker-compose up -dThe fastest solution is often to use a different host port:
Docker run:
# Map host port 8080 to container port 80
docker run -p 8080:80 your-imagedocker-compose.yml:
services:
web:
image: nginx
ports:
- "8080:80" # Host port 8080 -> Container port 80Then access your application at http://localhost:8080 instead of port 80.
On Windows, the WinNAT service can block ports. This is a common fix:
Open PowerShell as Administrator and run:
# Stop WinNAT
net stop winnat
# Start your Docker container
docker-compose up -d
# or
docker start <container_name>
# Restart WinNAT
net start winnatThis temporarily releases ports held by WinNAT, allowing Docker to bind to them.
Hyper-V reserves dynamic port ranges that may include common ports like 80, 443, or 3000. To fix this permanently:
Check excluded port ranges:
netsh interface ipv4 show excludedportrange protocol=tcpReset the dynamic port range to avoid conflicts:
# Run as Administrator
netsh int ipv4 set dynamic tcp start=49152 num=16384
netsh int ipv6 set dynamic tcp start=49152 num=16384Reserve your specific port before Hyper-V does:
# Disable Hyper-V temporarily
dism.exe /Online /Disable-Feature:Microsoft-Hyper-V
# Restart
# Reserve your port
netsh int ipv4 add excludedportrange protocol=tcp startport=80 numberofports=1
# Re-enable Hyper-V
dism.exe /Online /Enable-Feature:Microsoft-Hyper-V /All
# RestartOn macOS Monterey and later, AirPlay Receiver uses ports 5000 and 7000 by default:
1. Open System Preferences (or System Settings on macOS Ventura+)
2. Go to Sharing (or General > AirDrop & Handoff)
3. Uncheck AirPlay Receiver
Alternatively, check if Control Center is using your port:
lsof -i :5000If you see "ControlCe" in the output, that's the AirPlay Receiver.
Sometimes Docker Desktop itself has stale port bindings:
On Windows/macOS:
1. Right-click the Docker whale icon in the system tray
2. Select Restart
3. Wait for Docker to fully restart
4. Try running your container again
On Linux:
sudo systemctl restart dockerAfter restarting, verify Docker is running:
docker infoChecking all port bindings at once:
# Linux/macOS - show all listening ports
sudo lsof -i -P -n | grep LISTEN
# Windows
netstat -an | findstr LISTENINGDocker port range configuration:
If you frequently hit port conflicts, consider configuring Docker to use specific port ranges. In daemon.json:
{
"default-address-pools": [
{"base":"172.80.0.0/16","size":24}
]
}Avoiding port conflicts in CI/CD:
Use dynamic port assignment by leaving the host port empty:
ports:
- "80" # Docker assigns an available host portThen use docker port <container> 80 to discover the assigned port.
WSL2 port forwarding issues:
If you're using Docker with WSL2 and can't access ports from Windows:
# Get WSL IP
wsl hostname -I
# Add port proxy if needed
netsh interface portproxy add v4tov4 listenport=80 listenaddress=0.0.0.0 connectport=80 connectaddress=<WSL_IP>Kubernetes/Minikube conflicts:
If you have Minikube or Kubernetes running, they may reserve ports. Check with:
kubectl get svc --all-namespacesdockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
Error response from daemon: manifest for nginx:nonexistent not found: manifest unknown: manifest unknown
How to fix 'manifest for image:tag not found' in Docker
Error response from daemon: invalid reference format: repository name must be lowercase
How to fix 'repository name must be lowercase' in Docker
Error response from daemon: No such image
How to fix 'No such image' in Docker
Error response from daemon: Container is not running
How to fix 'Container is not running' when using docker exec