---
slug: "django-csrf-elb-apache2-uwsgi"
title: "Failure of Django CSRF Token Authentication: ELB -> Apache2 -> uwsgi"
description: "Fix Django CSRF token failure on an AWS ELB → Apache2 → uWSGI stack. The pitfall is the HTTP/HTTPS scheme detection when switching from mod_wsgi to uWSGI."
url: "https://www.ytyng.com/en/blog/django-csrf-elb-apache2-uwsgi"
publish_date: "2016-09-16T03:24:38Z"
created: "2016-09-16T03:24:38Z"
updated: "2026-05-11T13:02:45.067Z"
categories: ["Django", "Linux"]
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20230812/0ebb2d9ba7534619bfe8dbcec84a6783.png.webp?width=768"
has_video: false
has_music: false
video_urls: []
music_urls: []
lang: "en"
---

# Failure of Django CSRF Token Authentication: ELB -> Apache2 -> uwsgi

<p>Originally, the configuration was AWS ELB -> Apache2 -> mod_wsgi, but after changing the Django server to use uWSGI, the configuration became AWS ELB -> Apache2 -> uWSGI. After this change, I started experiencing issues with Django's CSRF authentication, such as when submitting a login form.

When I checked with DEBUG = True, I saw the following message:

Access Forbidden (403)

The request was aborted due to failure in CSRF verification.
Help

Reason given for failure:

    Referer checking failed - https://example.com.com/some-path/ does not match any trusted origins.
    
In general, this can occur when there is a genuine Cross-Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:

    Your browser is accepting cookies.
    The view function passes a request to the template's render method.
    In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
    If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.

You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.

You can customize this page using the CSRF_FAILURE_VIEW setting.

The ELB receives HTTPS, sends requests to Apache on port 80, and uWSGI is listening for HTTP protocol (not uWSGI protocol).

The Apache configuration is as follows:

ProxyPass / http://127.0.0.1:8081/
ProxyPassReverse / http://127.0.0.1:8081/

Alias /static/ /var/django/xxxxx/staticfiles/
ProxyPass /static/ !

Something like this.

Upon searching the Django code, I found in csrf.py:

REASON_BAD_REFERER = "Referer checking failed - %s does not match any trusted origins."

It appears that adding the domain to CSRF_TRUSTED_ORIGINS should work.

CSRF_TRUSTED_ORIGINS = [".example.com"] This should do the trick.</p>
<p></p>
