FastAPI Troubleshooting
Introduction
FastAPI errors often look cryptic until you recognize the pattern—422 validation bodies, import path mistakes, CORS in the browser only, or Nginx 502 when Uvicorn is down. This chapter maps common symptoms to fixes and links back to the chapters where each topic is taught in depth.
Prerequisites
- You have run at least one FastAPI app locally
- Basic terminal and log reading skills
Diagnostic Flow
Error → classify (install / validation / DB / auth / deploy) → read logs → fix one layer| Layer | Where to look |
|---|---|
| Local dev | Terminal running uvicorn |
| Production app | journalctl -u fastapi-app, Gunicorn error log |
| Nginx | /var/log/nginx/error.log |
| Database | MySQL logs, SQLAlchemy traceback |
Installation and Import Errors
ModuleNotFoundError: No module named 'fastapi'
Cause: venv not activated or packages installed globally.
Fix:
source .venv/bin/activate
pip install -r requirements.txt
which pythonSee environment chapter.
Error loading ASGI app. Could not import module "app.main"
Cause: Wrong working directory or PYTHONPATH.
Fix: Run uvicorn from directory containing app/ package:
uvicorn app.main:app --reloadImportError / circular import
Cause: main.py imports routers that import main.
Fix: Layer api/, models/, schemas/, deps.py—import routers inside factory or after app creation. See project structure.
Server and Port Issues
Address already in use (port 8000)
lsof -i :8000
kill <PID>
# or
uvicorn app.main:app --port 8001uvicorn: command not found
Activate venv; pip install "uvicorn[standard]".
Validation and 422 Errors
422 Unprocessable Entity
Cause: Request body, query, or path failed Pydantic validation.
Fix: Read response detail array—each item has loc, msg, type.
{
"detail": [
{"loc": ["body", "price"], "msg": "Input should be greater than 0", "type": "greater_than"}
]
}See path/query/body and Pydantic.
Pydantic v1 vs v2 mix
Symptoms: ValidationError, .dict() missing, class Config ignored.
Fix: Use model_dump(), model_config = ConfigDict(...)—Pydantic chapter.
Authentication and JWT
401 Could not validate credentials
- Missing
Authorization: Bearer <token>header - Expired token
SECRET_KEYchanged between login and request
Login returns 422 with JSON body
Cause: OAuth2PasswordRequestForm expects form data, not JSON.
Fix:
curl -X POST http://127.0.0.1:8000/api/v1/auth/login \
-d "username=alice&password=secret123"403 on todo or resource
Expected when accessing another user's data—permissions chapter.
Database Errors
sqlalchemy.exc.OperationalError
Wrong DATABASE_URL, MySQL down, or firewall.
mysql -u user -p -h 127.0.0.1 dbnameSee SQLAlchemy chapter and MySQL troubleshooting.
No such table / Unknown column
Run migrations:
alembic upgrade headSee Alembic chapter.
Session leaks / too many connections
Ensure get_db uses try/finally with db.close()—dependency injection.
CORS (Browser Only)
Access blocked by CORS policy
curl works, browser fails → configure CORSMiddleware origins.
allow_origins=["http://localhost:5173"]See middleware and CORS. Compare Flask CORS.
Async and Performance
Blocking ORM in async def route
Event loop stalls under load.
Fix: Use def route for sync SQLAlchemy, or async database, or run_in_threadpool.
App hangs on startup
Lifespan blocking on DB/Redis connect—add timeouts and logging in lifespan.
Production and Nginx
502 Bad Gateway
Uvicorn/Gunicorn not running or wrong proxy_pass port.
sudo systemctl status fastapi-app
curl http://127.0.0.1:8000/healthSee deployment and production project.
504 Gateway Timeout
Increase Gunicorn --timeout and Nginx proxy_read_timeout.
WebSocket fails through Nginx
Add Upgrade and Connection headers—deploy chapter.
OpenAPI and Docs
/docs empty or 404
docs_url=None in production settings—intentional; use env flag for staging.
Authorize in Swagger fails
tokenUrl must match login route path exactly.
Quick Reference Table
| Symptom | Likely cause | First action |
|---|---|---|
| No module fastapi | venv | Activate + pip install |
| Could not import app.main | cwd | Run from project root |
| 422 | validation | Read detail |
| 401 JWT | token/header | Check Bearer + expiry |
| Login 422 | JSON vs form | Use form POST |
| CORS browser | origins | CORSMiddleware |
| 502 | app down | systemctl status |
| No table | migrations | alembic upgrade |
| Blocking async | sync ORM | Use def route |
FAQ
Where is full traceback?
Dev terminal; production Gunicorn error log—never expose to clients.
pytest passes, manual fails?
Different Settings or missing dependency_overrides.
Docker container exits?
docker logs <container>—often migration or missing env var.
Still stuck?
Minimal repro: one route + one schema; bisect until it breaks.
Report doc typo?
Planning doc in Chinese?
frontend/gen_article_plan/fastapi.md.