First, check who is showing the 502 page. If the page says nginx, your origin server is probably angry. If it says Cloudflare, the problem may be between Cloudflare and your origin, or at Cloudflare’s edge. Cloudflare says 502 and 504 errors can happen when the origin server is unreachable, overloaded, or returning bad data [source: Cloudflare].
TLDR: A 502 Bad Gateway means one server asked another server for help and got junk, silence, or a rude door slam. For example, a store gets 10,000 visits during a sale, and 37% of checkout requests fail with 502 errors. If the page has a Cloudflare logo and a Ray ID, start with Cloudflare and connection logs. If the page is plain and says nginx, start with your app, PHP, Node, upstream server, or reverse proxy settings.
What a 502 error means, in plain human words
A 502 error is a broken handoff.
Think of your website like a burger shop.
- The browser is the hungry customer.
- Cloudflare is the front counter.
- Nginx is the kitchen manager.
- Your app server is the cook.
- The database is the fridge.
The customer asks for a burger. The counter asks the kitchen. The kitchen asks the cook. The cook screams, drops the spatula, or disappears.
Result: 502 Bad Gateway.
It is not always one villain. That is the annoying part. A 502 can come from Nginx, Cloudflare, PHP-FPM, Node.js, Gunicorn, Puma, Apache, Docker, Kubernetes, a firewall, or a server that simply ran out of breath.
Nginx 502 vs Cloudflare 502: spot the costume
The error page is your first clue.
If it is an Nginx 502
You may see a plain page like this:
502 Bad Gateway
nginx
This usually means Nginx reached for an upstream service and got a bad reply. Or no reply. Nginx is saying, “I tried. The thing behind me failed.”
Common causes include:
- PHP-FPM is down. WordPress sites love this one.
- Node.js crashed. One bad deploy, boom.
- The upstream port is wrong. Nginx points to port 3000, but the app runs on 3001.
- Unix socket permissions are bad. Classic tiny setting, giant headache.
- The app timed out. Nginx waited, then gave up.
- The app returned malformed headers. Servers hate weird headers.
If it is a Cloudflare 502
A Cloudflare error page often has branding. It may show:
- Cloudflare logo
- Ray ID
- Your location
- Browser working
- Cloudflare working
- Host error
That Ray ID matters. Save it. Do not ignore it like the “check engine” light. It helps support teams trace the request.
A Cloudflare 502 often means Cloudflare asked your origin server for a page, but the origin replied badly or not at all. Sometimes Cloudflare has an edge issue. Most times, the origin is the grumpy part.
The fastest way to diagnose it
Start with the visible error page. Then work inward.
- Look at the page branding. Is it Nginx or Cloudflare?
- Check if the site works without Cloudflare. Use the origin IP if safe and allowed.
- Check Nginx error logs. This is where the bodies are buried.
- Check app logs. PHP, Node, Python, Ruby, Java. Pick your monster.
- Check CPU, memory, and disk. Full disks create strange pain.
- Check firewalls. Cloudflare IPs may be blocked.
- Check recent deploys. The bug is often still warm.
Honestly, it feels like 502 errors know when you are tired. They appear at 4:58 PM. Then one log file quietly says, “upstream timed out,” like that explains your whole evening.
What to check in Nginx
Nginx is direct. It writes useful errors if logging is enabled.
Check files like:
/var/log/nginx/error.log/var/log/nginx/access.log- Your site-specific log file
Look for lines with:
connect() failedupstream timed outconnection refusedno live upstreamsupstream sent too big headerrecv() failed
Each message gives a hint.
Connection refused means the app is not listening where Nginx expected it.
Upstream timed out means the app was too slow.
Too big header may mean cookies are huge. Yes, cookies can ruin your day.
No live upstreams means Nginx thinks all backend servers are dead.
What to check in Cloudflare
Cloudflare sits in front. That means it sees traffic before your server does.
Check these items:
- Ray ID. Copy it from the error page.
- Firewall events. Rules may block real traffic.
- DNS records. Make sure the record points to the right origin.
- SSL mode. Flexible SSL can cause odd loops and failures.
- Origin health. Is the server online from outside?
- Cloudflare status page. Rare, but worth a quick check.
Also check if your origin blocks Cloudflare IP ranges. This happens more than people admit. A server firewall sees many requests from Cloudflare and thinks, “Attack!” Then it blocks the helper. Great job, firewall. Very cool.
A simple test that saves time
Use curl.
Test Cloudflare path:
curl -I https://example.com
Test origin path:
curl -I --resolve example.com:443:ORIGIN_IP https://example.com
If Cloudflare gives 502, but the origin works, the issue may be Cloudflare settings, DNS, SSL, or firewall rules.
If the origin gives 502 too, Cloudflare is not the main problem. Your server is the mess.
That second command feels nerdy. It is also a tiny flashlight in a very dark server room.
Common fixes for Nginx 502
- Restart the app service. Try PHP-FPM, Node, or your backend process.
- Fix upstream address and port. Check
proxy_passorfastcgi_pass. - Increase timeouts. Use this carefully. Slow apps still need fixing.
- Check permissions. Especially for sockets.
- Reduce large headers. Trim cookies and auth tokens.
- Add more workers. If traffic is crushing the app.
Common fixes for Cloudflare 502
- Allow Cloudflare IPs. Update firewall rules.
- Check SSL mode. Full or Full Strict is often better than Flexible.
- Fix DNS records. Old origin IPs cause chaos.
- Pause Cloudflare briefly. Test only. Do not forget to turn it back on.
- Review WAF rules. One strict rule can break normal users.
- Check server load. Cloudflare cannot save a dead origin.
Quick cheat sheet
| Clue | Likely place to start |
|---|---|
| Plain “nginx” page | Nginx and app server logs |
| Cloudflare page with Ray ID | Cloudflare dashboard and origin connection |
| Works on origin IP | Cloudflare settings, DNS, firewall |
| Fails on origin IP | Server, app, database, upstream |
| Only fails during traffic spikes | Capacity, workers, timeouts, caching |
Final rule
Do not guess for an hour. Identify the error page. Grab the Ray ID if Cloudflare shows one. Read the Nginx error log. Test the origin directly. Then fix the broken handoff.
A 502 is not magic. It is just one server saying, “The next server made this weird.” Find that next server, and the mystery gets much smaller.