Flask development server

localhost:5000

Flask’s development command starts on 127.0.0.1:5000 by default. A failure on this port is usually one of four distinct problems: the process did not start, another process owns 5000, the app has no matching route, or the server is bound somewhere your client cannot reach.

Checked against Flask 3.1 documentationWindows · macOS · Linux · DockerUpdated September 5, 2026
Flask default5000
Default bind127.0.0.1
ProtocolHTTP
Production ready?No

Start a minimal Flask app

# hello.py
from flask import Flask

app = Flask(__name__)

@app.get("/")
def hello():
    return {"status": "ok"}

# Start it from the project environment
flask --app hello run --debug

The terminal should print http://127.0.0.1:5000. Use that exact URL and keep the terminal open so request logs and exceptions remain visible.

Diagnose before changing configuration

SymptomMeaningAction
ERR_CONNECTION_REFUSEDNo listener at the requested address and port.Read the startup error and inspect port 5000.
Address already in useAnother process owns 5000.Identify it or run Flask with --port 5001.
HTTP 404Flask received the request, but no route matched.Check the route path, slash, blueprint prefix, and HTTP method.
HTTP 405The path exists but does not allow that method.Compare GET, POST, PUT, and the route’s methods.
Works locally, not from phoneThe default loopback bind is local to the computer.Bind deliberately to a LAN interface and apply firewall controls.
# Windows PowerShell
Get-NetTCPConnection -LocalPort 5000 -State Listen

# macOS or Linux
lsof -nP -iTCP:5000 -sTCP:LISTEN

# Direct request
curl -i http://127.0.0.1:5000/

Address already in use

Flask’s own documentation recommends identifying the existing program or selecting a different port:

flask --app hello run --port 5001

On macOS Monterey and later, AirPlay Receiver may occupy port 5000. If the listener belongs to that system service, either choose 5001 or disable AirPlay Receiver in System Settings when you do not use it.

Do not blindly kill the reported PID. Confirm the executable and whether another project or system feature depends on it.

The root works, but /login or /api fails

That is an application-routing issue, not a localhost failure. Flask routes are explicit and method-specific:

@app.get("/api/health")
def health():
    return {"status": "ok"}

@app.post("/login")
def login():
    ...

A browser address bar sends GET. It will receive 405 from a POST-only /login route. If the route is registered on a blueprint with url_prefix="/api", include that prefix in the request.

LAN and Docker access

# Reachable on the local network; development only
flask --app hello run --host 0.0.0.0 --port 5000

# Docker host mapping
docker run --rm -p 5000:5000 your-image

In a container, Flask must listen on 0.0.0.0 inside the container as well as having a published host port. From another device, browse to the computer’s LAN IP, not localhost—“localhost” always means the device making the request.

Flask’s development server and interactive debugger are not for production. The debugger can execute Python code. Keep it on trusted development networks only.

Official references