If you call app.get('/')
without the @
decorator, FastAPI registers nothing. That means no route exists, so every request returns 404. This is the most common mistake:
# ❌ WRONG:
app.get('/')
def root():
return {'msg': 'hello'}
# ✅ CORRECT:
@app.get('/')
def root():
return {'msg': 'hello'}
Often, your script will include routers or static mounts, but if the decorators aren’t applied properly, nothing gets registered. Here's a robust minimal example that you can copy into main.py
and test:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/")
def hello():
return {"hello": "world"}
@app.get("/abc")
def abc():
return {"hello": "abc"}
Run it with:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
Navigate to GET /
, /abc
, or /static/…
—they should all work. If GET /
still returns 404, re‑check your decorators.
If you're including an APIRouter
:
from fastapi import FastAPI, APIRouter
router = APIRouter(prefix="/items")
@router.get("/")
async def list_items():
return ["a", "b"]
app = FastAPI()
app.include_router(router)
Your route is reachable at /items/
, not /
. So GET /
→ 404, GET /items/
→ 200 with ["a","b"]
. This is another source of “missing” routes.
root_path
If you're hosting behind a proxy (Nginx, Traefik, API Gateway, etc.) that strips or adds leading path segments, FastAPI’s OpenAPI UI /docs or even paths can break. Use the root_path
feature:
Via code:
app = FastAPI(root_path="/myapp")
Via Uvicorn CLI:
uvicorn main:app --root-path "/myapp"
This ensures both routing and docs work with the prefixed path.
Check you’re in the correct working directory (project root).
Temporarily hardcode a simple root route:
@app.get("/")
def debug_root():
return {"ok": True}
Print the registered routes to verify:
for r in app.routes:
print(r.path, r.methods)
Then run your service and inspect output to know exactly what endpoints exist.