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

Errno 13 Permission Denied While Attempting to Bind Address in Python

Verified FixPython 3.10+Python Native Socket / UvicornSilo: environment

Quick Fix / Solution Rapide

Change the server bind port to an unprivileged port (> 1024, e.g. 5000, 8000, 8080) or execute with elevated privileges (root / sudo).

Root Cause Analysis

This error occurs when Python tries to bind a network socket (using socket.bind() or running web frameworks like Uvicorn, Flask, or Gunicorn) to a privileged port (ports 1 through 1023, such as port 80 or port 443) without root/administrator privileges.

1. Privileged Port Restrictions on POSIX Systems

On Linux, macOS, and BSD systems, network ports below 1024 are classified as privileged ports reserved for system services. Standard unprivileged user processes cannot bind to these ports and receive PermissionError: [Errno 13] Permission denied.

2. Binding to Restricted IP Addresses

Attempting to bind a server socket to an IP address not assigned to any local network interface (e.g. attempting to bind to a remote server's public IP) causes socket binding failures.

3. Port Already Held by System Daemon

If another system service (such as Apache or Nginx) is listening on port 80, attempting to bind as a non-privileged user results in permission denial.

4. Container User Permissions

Running Docker containers with USER 1000 (non-root) while configuring the application to listen on port 80 triggers Errno 13.

Reproduction Code (MCVE)

Example: Bug Reproduction
# **Note de reproductibilité :** Dépendant des permissions du système d'exploitation.
raise PermissionError('[Errno 13] Permission denied: ("127.0.0.1", 80)')

Solution 1: Bind to an Unprivileged Port (> 1024)

Configure development servers to bind to standard application ports such as 8000, 8080, or 5000.

Example: Recommended Solution
import socket

# Bind to safe unprivileged port
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_sock.bind(('127.0.0.1', 8080))
print(f'Socket successfully bound to: {server_sock.getsockname()}')
server_sock.close()

Solution 2: Use Reverse Proxy (Nginx) for Port 80/443 Routing

Run Python web servers (Gunicorn/Uvicorn) on port 8000 as an unprivileged user and use Nginx to proxy public traffic from port 80/443.

Example: Alternative Solution
print('Standard production architecture:')
print('Public Internet (Port 80/443) -> Nginx (Reverse Proxy) -> Python Gunicorn (127.0.0.1:8000)')

A common mistake in production is running Python web servers directly under sudo python app.py on port 80. Running application code as root creates serious security vulnerabilities. Always use a reverse proxy (Nginx, Traefik, or Caddy) or grant socket binding capabilities via setcap 'cap_net_bind_service=+ep' $(which python3). Edge cases occur in Windows when Internet Connection Sharing or WSL reserves port ranges: use netstat -ano to inspect port assignments. Contrast this error with OSError: [Errno 98] Address already in use, which occurs when a port is valid but already bound by another process.