Synthetic Industry

Troubleshooting guide · updated 2026-10-11

nginx 502 or 504? Read which stage failed before you change anything

Tell an upstream that refused the connection from one that answered too slowly, using the status code, the error log and the proxy settings that apply to the failing route.

The two codes mean different things

A 502 and a 504 are both produced by nginx on behalf of something behind it, and the two codes point to different places. MDN defines a 502 as the gateway receiving an invalid response from the upstream, and a 504 as no response arriving in time; MDN also says a gateway that gets no HTTP response at all should send a 504. The split used in this guide is how nginx behaves in practice rather than something MDN states: a connection that is refused or reset, or a reply that is not valid HTTP, typically ends as a 502, while an upstream that does not answer in time ends as a 504. A 504 has two different causes, which the error log tells apart. If nginx reached the upstream and then waited for a reply, the application is slow or stuck. If nginx never managed to connect, nothing is answering at that address at all: the host is down, the address is wrong or a firewall is dropping the packets. Knowing which one you have halves the search, because a 502 points at whether the application is listening where nginx expects it, a read-stage 504 points at how long the application takes and how long nginx is willing to wait, and a connect-stage 504 points at the network path.

  • 502: check that the application is running, listening on the address nginx uses and not crashing on start.
  • 504 while reading the response: check how long the failing request takes and which timeout nginx applies to that route.
  • 504 while connecting: check that the host is up, the address and port are right and nothing between nginx and the application drops packets. Raising a read timeout cannot help.
  • Neither: a 500 or 403 page is usually the application's own response passed through.

Read the error log, not the access log

The access log records the status that was returned. The error log records why. For an upstream failure the entry names the upstream address and the stage nginx had reached: connecting, sending the request or reading the response. The exact wording varies with the nginx version, so match on the stage rather than a memorised phrase. Take twenty lines around one failure with the same timestamp as a visitor report, and remove addresses and tokens before sharing them. A connect-stage failure for every request means nothing is accepting connections at that address: a refusal ends as a 502, while no answer at all ends as a 504 after the connect timeout. A read-stage failure for one route only means that route is slow or stuck.

  • Find the error_log directive in the configuration, since the default path depends on how nginx was installed.
  • Match the timestamp of a known failing request to the entry before drawing a conclusion.
  • Count how often the same stage appears; a mix of stages suggests more than one cause.

The timeouts that decide a 504, and the one that does not mean slow

nginx documents three proxy timeouts, each 60 seconds by default. The connect timeout limits how long nginx waits to establish a connection. The send and read timeouts apply between two successive writes or reads, not to the whole request or response, so a response that trickles in steadily can outlast a 60 second read timeout while a silent one cannot. That is why a long report that streams output may work while a shorter one that computes everything before answering fails. When the connect timeout is what expired, the error log says the stage was connecting and the problem is the network path or the address, not the speed of the application; lengthening the read timeout will not change that. Raise a read timeout only for a route whose duration you have measured and which is meant to be slow; otherwise the visitor waits longer for the same error and workers stay busy.

  • Read the stage in the error log first: connecting means the address, reading means the speed.
  • Measure the request duration directly against the application, bypassing nginx.
  • Apply a longer timeout inside the location that serves that route, not globally.
  • If a request regularly needs more than a minute, a background job with a status page is a better design than a longer wait.

Change one thing, test it, then reload

Test an edit with nginx's configuration check before reloading, and read the result of the reload on the live pages, not only the command output. nginx documents that on reload the master process checks the new configuration and, if it is invalid, keeps running with the old one, so a failed check does not take the site down, but it also means your change has not taken effect. After the reload, request each named URL repeatedly and watch the error log for the same window. A fix is only a fix if the URL succeeds consistently and the log is quiet.

  • Run the configuration test, then reload, then request the failing URLs 20 times.
  • Keep the previous configuration file so you can revert in one step.
  • If the log shows the application crashing, restarting nginx will not help; look at the application.

What this does not cover, and when to ask for help

Some gateway errors are not generated by your nginx at all. A CDN or cloud load balancer in front of it can return its own 502 or 504 page, and a different nginx on another machine can be the one failing. An application that crashes because of a bug needs a bug fix. A server that has run out of disk or memory needs a different repair. The fixed nginx repair job covers one site served by proxy_pass to an HTTP upstream, finds the cause from the logs, tests the change and writes down the way back. It will not promise uptime, and it will say plainly when the cause lies in the application.

Sources and limits

  • MDN: 502 Bad Gateway Checked 2026-10-11.
    • A 502 means a gateway or proxy received an invalid response from the upstream server.
    • If the gateway gets no HTTP response at all from the origin, it should send a 504 instead.
  • MDN: 504 Gateway Timeout Checked 2026-10-11.
    • A 504 means the gateway or proxy did not get a response from the upstream in time.
  • nginx: ngx_http_proxy_module Checked 2026-10-11.
    • proxy_connect_timeout, proxy_send_timeout and proxy_read_timeout each default to 60 seconds.
    • proxy_next_upstream defaults to error and timeout.
  • nginx: controlling nginx Checked 2026-10-11.
    • A reload checks the new configuration and keeps the old one running if the new one is invalid.