How to Fix a 504 Gateway Timeout Error
Find which gateway gave up and why, then apply the fix that fits your role.
Updated
TL;DR
504 Gateway Timeout means the site's own server answered too slowly, so the nginx, load balancer or CDN in front of it stopped waiting. The fault is usually the site's: wait a minute and retry once, or ask for less data if one big request keeps failing.
How gateways and clients show a 504
The gateway that gave up writes the page; clients add their own wording around the code.
| Where | What you see |
|---|---|
| nginx (default page, server_tokens off) | 504 Gateway Time-out nginx |
| HAProxy (built-in error page) | 504 Gateway Time-out The server didn't respond in time. |
| Chrome (504 with an empty body) | This page isn't working. example.com took too long to respond. HTTP ERROR 504 |
| Older curl, proxy answered CONNECT with 504 | curl: (56) Received HTTP code 504 from proxy after CONNECT |
| Newer curl, same case (latest releases show 7, not 56) | curl: (56) CONNECT tunnel failed, response 504 |
| Python urllib behind nginx | urllib.error.HTTPError: HTTP Error 504: Gateway Time-out |
| Node.js with axios | AxiosError: Request failed with status code 504 |
Why this happens
Each gateway gives the app a time limit, and this request ran past it.
Typical causes are heavy work, such as a large data query, and a server so short of resources that it falls behind.
Diagnose your 504 first
Two browser checks first, then three that name the gateway, the sender and the stalled stage.
Open the site's home page or another light page; if it loads while one action keeps failing, that action needs longer than the gateway allows.
Look at the error page; Cloudflare branding means the site's own server sent the 504, while a bare page showing only 'cloudflare' means Cloudflare did.
Time it with curl -w '%{time_total}'; about 60 seconds fits nginx or ALB defaults, 29 or 30 API Gateway, 10 an ALB that never connected.
Fetch an https:// URL with curl -v -x; if the first '<' status line already reads 504, your proxy sent it, not the site.
In your nginx error log, a timeout 'while connecting to upstream' means no connection opened; 'while reading response header' means the app answered too late.
Solutions ranked by effectiveness
Visitors need only the first card; API users and site owners read on.
- Most common fix
Wait a minute, then retry once
Applies to sites you do not run. A 504 can clear on its own once the server catches up.
Wait a minute or two, then reload the page once.
Before sending a payment or form again, look for a confirmation first.
In scripts, repeat GET requests after a pause, and leave POST requests alone.
Report a lasting 504 to the site's owner with the page address and the time.
- For developers
Ask for less in each request
Applies when one big call, such as a full export or a year of records, fails every time. Fetch it in pages or shorter ranges, or use the API's export job if it has one.
import json, urllib.request page, items = 1, [] while True: url = f"https://api.example.com/items?page={page}&per_page=100" with urllib.request.urlopen(url, timeout=60) as res: batch = json.load(res) if not batch: break items += batch page += 1 print(len(items), "items in", page, "requests") - Site owners
Raise one limit, or answer later
Applies when the site is yours. Make the endpoint faster first, and lengthen a limit only where work is meant to take minutes.
In nginx, set a higher proxy_read_timeout inside that one location block.
On an AWS ALB, raise Connection idle timeout, which accepts 1 to 4000 seconds.
On API Gateway, request a longer integration timeout for Regional or private REST APIs.
Behind Cloudflare, waits past 125 seconds end in 524; return 202 with a status URL.
Stop the 504 from coming back
Habits for site owners that keep long-running pages within every gateway's limit.
Stream long responses as they are built; nginx and an AWS ALB restart their timers whenever data arrives.
Track 95th percentile response times per path and fix paths drifting toward the limit.
Move work the reply does not need, such as sending emails, into a background job.
Serve exports that take over two minutes from a DNS-only subdomain, outside Cloudflare's proxy.
Related errors
Learn more
FAQ
Residential proxies in Scrapy
Geonode's Scrapy guide wires the proxy into one downloader middleware, apart from your spider code.


