Forbidden (403) CSRF verification failed. Request aborted.
Django rejected a POST because the CSRF token was missing, wrong, or the request origin isn’t trusted.
Seen on:
Python
Meaning
Forms need {% csrf_token %}; AJAX needs the X-CSRFToken header. Since Django 4.0, HTTPS sites behind proxies also need CSRF_TRUSTED_ORIGINS with the scheme (https://example.com).
Common causes
- Form missing {% csrf_token %}
- AJAX request without X-CSRFToken
- Django 4+: origin not in CSRF_TRUSTED_ORIGINS
- Cookies blocked / CSRF cookie missing
- Proxy not setting X-Forwarded-Proto
⚡ Quick fix
- Add {% csrf_token %} inside POST forms
- Send the token header in fetch/axios
- Set CSRF_TRUSTED_ORIGINS = ["https://example.com"]
- Set SECURE_PROXY_SSL_HEADER behind HTTPS proxies
Detailed fix by platform
Python
CSRF_TRUSTED_ORIGINS = ["https://example.com", "https://www.example.com"]
How to diagnose
- Reason — The debug page gives the exact reason
- Origin — Listed in trusted origins?
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Was this page helpful?
Report a correction or suggest an improvement
Last updated 2 Oct 2026