top of page

Django 502 Bad Gateway

Your Django app runs perfectly with runserver, but in production Nginx shows "502 Bad Gateway" on every page, or only on some requests. Users can't reach the site and the error page tells you nothing. A Codersarts Django engineer finds the break between Nginx and your app and gets it serving again.

A 502 Bad Gateway means Nginx couldn't get a valid response from the application server behind it, usually Gunicorn or uWSGI. The most common causes are: the application server isn't running or crashed on startup, Nginx is pointing to the wrong socket or port, Nginx doesn't have permission to access the socket, workers are killed for taking too long, or the server runs out of memory. The Nginx error log almost always names which one it is.



Typical symptoms

502 on all pages, 502 on slow pages only, errors after a deploy or reboot, intermittent 502s under load

Most common causes

Gunicorn not running, socket or port mismatch, socket permissions, worker timeouts, out of memory

How we fix it

Read Nginx and Gunicorn logs, test the app server directly, fix config and startup, tune workers

Turnaround

Same-day diagnosis; most fixes in 24–48 hours

Price

Live Debug from $20; fixed-price quote for the full fix



Signs Your Django App Has a 502 Problem

  • Every page returns 502 Bad Gateway, but python manage.py runserver works

  • The site broke after a deploy, a server reboot, or a code change

  • Nginx error log shows connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)

  • Nginx error log shows (13: Permission denied) for the socket

  • Nginx error log shows upstream prematurely closed connection

  • Only slow pages, reports, or file uploads return 502

  • Gunicorn logs show WORKER TIMEOUT or workers being restarted

  • 502 errors appear during traffic peaks



Why Django Returns 502 Bad Gateway


In a typical production setup, Nginx receives the request and forwards it to Gunicorn, which runs your Django code. A 502 appears when that handoff fails. The problem is almost never in Nginx itself.


1. Gunicorn isn't running or crashed on startup

If Django fails while loading, Gunicorn can't start. Common triggers are a missing environment variable, a settings error, a failed import after installing new code, a wrong WSGI module path in the service file, or a virtual environment that wasn't activated. With no application server listening, Nginx has nothing to forward to.


2. Nginx points to the wrong socket or port

The address in Nginx's proxy_pass must match exactly where Gunicorn listens. A socket path that changed, a different port, or Gunicorn binding to another interface all break the connection.


3. Socket permission problems

When Gunicorn uses a Unix socket, the user Nginx runs as needs permission to access it and every directory above it. Sockets placed in home directories or created with restrictive permissions produce "Permission denied" errors.


4. Workers killed for timing out

Gunicorn stops workers that take longer than its timeout, which is 30 seconds by default. Slow database queries, large exports, external API calls, or file processing inside a request cause the worker to be killed, and Nginx returns 502 for that request.


5. Out of memory

Too many workers for the server's memory, or requests that load large datasets, can trigger the operating system to kill Gunicorn processes. The result is intermittent 502s that often appear under load.



How We Diagnose the 502

  1. Read the Nginx error log. The exact message separates missing sockets, permission problems, and closed connections.

  2. Check the Gunicorn service. Review service status and logs for startup errors, crashes, and worker timeouts.

  3. Start Gunicorn manually. Run it in the foreground to reveal import, settings, or environment errors.

  4. Test the app server directly. Send a request to the socket or port without Nginx to isolate the failing layer.

  5. Validate Nginx configuration. Confirm proxy_pass matches the Gunicorn bind address and test the config.

  6. Check system resources. Look for memory pressure and processes killed by the operating system.



How We Fix It

Root cause

Fix

Gunicorn not starting

Fix the settings, import, or environment error, and correct the service file's paths and WSGI module

Socket or port mismatch

Align Nginx proxy_pass with Gunicorn's bind address

Socket permissions

Move the socket to a proper runtime directory and set ownership so Nginx can access it

Worker timeouts

Move slow work to background tasks, optimize slow queries, and set timeouts deliberately

Out of memory

Right-size worker count, reduce memory-heavy requests, and add swap or resources if needed

Breaks after reboot or deploy

Make Gunicorn start automatically as a managed service and add a deploy health check


We confirm the fix by testing normal pages, slow pages, and a restart of the server.



Example Fix


Situation: A Django booking platform on an Ubuntu server returned 502 on every page after the team deployed a new release and rebooted the server.


Cause: The new release read a new environment variable that wasn't in the Gunicorn service file, so Django failed during startup and Gunicorn never created its socket. Separately, the monthly report page regularly exceeded Gunicorn's 30-second timeout.


Fix: Added the environment variable to the service configuration, enabled the service to start on boot, added a post-deploy health check, and moved report generation to a background task with an emailed download link.


Result: The site came back immediately, survived reboots, and the report page stopped causing 502 errors.



How to Keep It From Happening Again

  • Add a health check after every deploy that fails the release if the app server doesn't respond.

  • Keep long-running work out of web requests by using a task queue.

  • Monitor Gunicorn worker restarts and memory so problems show up before users see 502s.



What You Get

  • Root cause confirmed and explained

  • Working Nginx and Gunicorn setup that survives restarts

  • Timeout and worker settings matched to your workload

  • Deploy health check or monitoring for the same failure



Frequently Asked Questions


What causes a 502 Bad Gateway in Django? Nginx can't get a response from Gunicorn or uWSGI. The app server isn't running, is listening somewhere else, can't be accessed because of socket permissions, or killed a worker because of a timeout or low memory.


Why does my Django site work with runserver but give 502 in production? Runserver doesn't use Nginx or Gunicorn. In production, service configuration, environment variables, socket paths, and permissions all have to be correct for Nginx to reach Django.


What's the difference between a 502 and a 504 error? A 502 means Nginx received no valid response, often because the app server is down or closed the connection. A 504 means Nginx waited too long for a response.


Should I just increase the Gunicorn timeout? Only as a short-term measure. If requests take longer than the timeout, the better fix is optimizing slow code or moving long tasks to a background worker.


Is a 400 Bad Request the same problem? No. A 400 in Django is often caused by ALLOWED_HOSTS not including your domain. That's a Django setting, while a 502 is a connection problem between Nginx and the app server.



Related Problems

  • Docker container exits immediately

  • AWS EC2 app not accessible

  • PostgreSQL queries suddenly slow

  • Python app memory leak

  • Next.js build failing on Vercel



Get Your Django Site Serving Again

Share your Nginx error log or the last deploy change. Get a diagnosis and a fixed price.


Get Help Now




bottom of page