SECURITY WARNING: Never run commands you don't understand. Always review code before execution. Use at your own risk.
Python New Added 9 September 2026

Django: Forbidden (403) CSRF verification failed. Request aborted.

Django rejected the POST because the CSRF token or the request Origin did not match the session. Behind a reverse proxy the cause is usually not a missing token at all: since Django 4.0 the Origin header is compared against CSRF_TRUSTED_ORIGINS, so a site served over HTTPS whose proxy forwards the request as plain HTTP fails every form.

Quick fix

Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.

Quick fix
# settings.py: the scheme is required, and it must match what the browser sees
CSRF_TRUSTED_ORIGINS = ["https://app.example.com"]

# Behind a proxy, tell Django the original scheme
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

# Nginx has to send it
proxy_set_header X-Forwarded-Proto $scheme;

# Templates: the token has to be inside the form
<form method="post">{% csrf_token %}</form>

# fetch() needs the cookie value in a header
headers: {"X-CSRFToken": getCookie("csrftoken")}

# Check the cookie is actually being set for this host
python manage.py shell -c "from django.conf import settings; print(settings.CSRF_COOKIE_DOMAIN)"

How to diagnose Python errors

Python errors cluster around the import system (which is really about sys.path and the active interpreter), environment management (which interpreter and which site-packages), and concurrency (the GIL, event loops, and pickling constraints in multiprocessing). A very large share of "module not found" reports are simply the wrong interpreter, which is why the first command should always identify it.

If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.

  1. Identify the interpreter and its paths: python -c "import sys; print(sys.executable); print(sys.path)". This resolves most import errors immediately.
  2. Install into the interpreter you are running, not the one on PATH: python -m pip install … rather than bare pip.
  3. Read tracebacks bottom-up. The last line is the exception; the frames above show the call chain, and the relevant frame is usually your code, not the library's.
  4. For encoding errors, name the encoding explicitly and decide on an error policy, such as open(path, encoding='utf-8', errors='replace'), rather than relying on the locale default.
  5. For multiprocessing pickling errors, move the target function to module level. Closures, lambdas and locally defined classes cannot be pickled.

Tools worth reaching for

  • python -m pip
  • python -c 'import sys; print(sys.path)'
  • pip check
  • py-spy dump
  • uv / pipx for isolation

Authoritative references

Primary documentation for this error, worth reading before applying any fix in production.

docs.djangoproject.com

Related Python errors

See all 35 Python errors →

Browse other categories

Something missing or wrong?

This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.