Geonode logo
Website and server errors

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.

WhereWhat 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 504curl: (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 nginxurllib.error.HTTPError: HTTP Error 504: Gateway Time-out
Node.js with axiosAxiosError: 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.

  1. 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.

    1. Wait a minute or two, then reload the page once.

    2. Before sending a payment or form again, look for a confirmation first.

    3. In scripts, repeat GET requests after a pause, and leave POST requests alone.

    4. Report a lasting 504 to the site's owner with the page address and the time.

  2. 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")
  3. 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.

    1. In nginx, set a higher proxy_read_timeout inside that one location block.

    2. On an AWS ALB, raise Connection idle timeout, which accepts 1 to 4000 seconds.

    3. On API Gateway, request a longer integration timeout for Regional or private REST APIs.

    4. 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.

  1. Stream long responses as they are built; nginx and an AWS ALB restart their timers whenever data arrives.

  2. Track 95th percentile response times per path and fix paths drifting toward the limit.

  3. Move work the reply does not need, such as sending emails, into a background job.

  4. Serve exports that take over two minutes from a DNS-only subdomain, outside Cloudflare's proxy.

Recheck a visitor's 504 reportState targeting loads your own page through a residential IP in the visitor's state.
Try residential proxies

Related errors

Learn more

FAQ

A server acting as a gateway or proxy got no timely answer from the server behind it. In a 408 the server waited for your request instead, and with no status at all your own client gave up.

It depends on your role: a visitor can only wait and reload, an API client can split the request into pages, and only the site's owner can repair the cause on the server.

Either the site's gateway timed out and its 504 passed through your proxy, or the proxy itself got no timely answer from the site. Geonode's error-handling reference lists no 504 among its proxy codes.

No status has that name; it blends two. With 502 Bad Gateway the reply was invalid, and with 504 Gateway Timeout no reply came in time.

Not for a 504 from the site. The gateway's timer starts only after your request reaches it, while it waits for the site's own server, so a distant exit adds to your total wait but not to that timer.

Wait. An nginx gateway with more than one app server already passes a timed-out GET to the next one by default, so a single 504 can mean several servers ran out of time.

Residential proxies in Scrapy

Geonode's Scrapy guide wires the proxy into one downloader middleware, apart from your spider code.