To fix a Django CORS error, allow the exact origin of your frontend and make sure django-cors-headers middleware runs early enough to add CORS headers to the response. An origin includes its scheme, hostname, and port, so http://localhost:3000 does not match http://localhost:8000 or https://localhost:3000.
Configure django-cors-headers
Install the package in the Python environment used by your Django project:
python -m pip install django-cors-headers
Then add the app to INSTALLED_APPS and put its middleware near the top of MIDDLEWARE, before middleware that might generate a response. The django-cors-headers setup instructions specifically call out Django’s CommonMiddleware and Whitenoise’s WhiteNoiseMiddleware.
INSTALLED_APPS = [
# ...
"corsheaders",
]
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
# ...
]
If CORS middleware runs too late, an earlier middleware may return a redirect, error, or other response before CORS headers can be added.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errors#1 Best Overall
Allow the frontend’s exact origin
For known frontend sites, use CORS_ALLOWED_ORIGINS to list each origin exactly, including http:// or https:// and any non-default port:
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"https://app.example.com",
]
The package defines an origin as a URI scheme, hostname, and port. Copy the browser request’s Origin value rather than guessing it. For a controlled set of subdomains, use CORS_ALLOWED_ORIGIN_REGEXES; see the origin regex setting documentation.
Rank #2
CORS_ALLOW_ALL_ORIGINS = True accepts requests from every origin. The maintainers warn this can unintentionally expose private data, so prefer an explicit allowlist unless accepting all origins is an intentional, understood choice. The options are documented under CORS settings.
When the OPTIONS preflight fails
For certain cross-origin requests, the browser first sends an OPTIONS preflight asking whether the server permits the intended method and headers. In the browser’s developer tools, inspect that OPTIONS request and its response—not just the later POST or PUT that the browser may never send.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →- Confirm the preflight response allows the requested method. The package’s
CORS_ALLOW_METHODSsetting has defaults; change them only if the request needs a method outside that list. - Check the requested headers against
CORS_ALLOW_HEADERS. Defaults includeauthorization,content-type,x-csrftoken, andx-requested-with. Add only custom headers the frontend actually sends. - Check whether a redirect, authentication failure, proxy, or application error is answering OPTIONS without the necessary CORS headers.
See the maintainer documentation for allowed methods and allowed headers.
Separate CORS errors from CSRF errors
CORS determines whether browser code may read a cross-origin response; it does not disable Django’s CSRF checks on unsafe requests. A request can pass CORS checks and still receive a Django 403 because CSRF validation failed. The package explains that CORS configuration does not exempt a site from Django’s secure-request Referer checks in its CORS and CSRF documentation. Django’s CSRF_TRUSTED_ORIGINS ticket history describes the setting’s role in secure-request Referer verification.
For cookie-authenticated or other unsafe HTTPS requests, add only the frontend origins that need to make those requests to CSRF_TRUSTED_ORIGINS, and send the CSRF token as Django expects. The lists may differ: a read-only frontend can be allowed by CORS without being trusted to make unsafe requests.
CORS_ALLOWED_ORIGINS = [
"https://read-only.example.com",
"https://read-and-write.example.com",
]
CSRF_TRUSTED_ORIGINS = [
"https://read-and-write.example.com",
]
If cross-site cookies are required, configure credentials deliberately and account for the cookies’ SameSite behavior. Allowing every CORS origin is not a substitute for designing cookie and CSRF protections.
Best Value
Use this diagnostic sequence
- In browser developer tools, copy the request’s exact
Originvalue, including scheme and port. - Match it against
CORS_ALLOWED_ORIGINSor the intendedCORS_ALLOWED_ORIGIN_REGEXESpattern. - Verify
django-cors-headersis installed in the active environment,corsheadersis inINSTALLED_APPS, andCorsMiddlewareprecedesCommonMiddlewareand other response-generating middleware. - If the browser reports a preflight failure, inspect the OPTIONS response, requested method, and requested headers.
- Check the actual response status, redirects, and proxy behavior. Confirm whether CORS headers appear on the response that failed, including error responses.
- If Django returns a CSRF 403, configure
CSRF_TRUSTED_ORIGINSseparately where needed and verify the frontend sends a valid CSRF token. - Check that your installed package and Django versions fall within the project’s documented support range.
The project currently documents support for Python 3.10–3.15 and Django 5.2–6.1; check its supported versions page if your environment differs.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

