About This Article
This article was created using an automated generation workflow utilizing generative AI. It reviews the HTTP status definitions in RFC 9110 and the official Nginx proxy/FastCGI documentation, organizing them into a format useful for initial web troubleshooting.Verification Status: 🧪 RFC and official Nginx info checked, 404 verified on localhost, intentional reproduction of 502/504 not performed
In Which Layer Do HTTP 404, 502, and 504 Occur? — Troubleshooting from the Nginx and Application Request Path
404, 502, and 504 are all HTTP statuses, but they do not share the same meaning. If you use Nginx as a reverse proxy or FastCGI gateway, do not jump to conclusions about the cause based on the status code alone; instead, check how far the request progressed along the path: Browser → Nginx → upstream.
- First, Distinguish the HTTP Meanings
- Having Nginx in Between Increases the Request Path
- Don’t Just Look at the URL for a 404
- Check the Upstream Boundary for a 502
- Find the “Slow Spot” for a 504
- Try It Now: Actually Trigger a 404 on Localhost
- Initial Triage
- GitHub Samples
- Official and Primary Information Sources
First, Distinguish the HTTP Meanings
| Status | RFC Meaning (Brief) | First Things to Consider |
|---|---|---|
| 404 Not Found | The origin server did not find a current representation for the target resource or is not willing to disclose that one exists | URL, routing, static files, application-side routes |
| 502 Bad Gateway | The gateway or proxy received an invalid response from the upstream server | Upstream connection destination, protocol, service, socket |
| 504 Gateway Timeout | The gateway or proxy did not receive a timely response from the upstream server | Upstream latency, timeout, bottlenecks |
The important thing is not to directly associate these with product-specific causes like 502 = PHPの文法エラー or 504 = Nginxが壊れた. What the RFC defines is the meaning of the HTTP response, while actual causes vary depending on your configuration.
Having Nginx in Between Increases the Request Path
sequenceDiagram
participant B as Browser
participant N as Nginx
participant U as Upstream / PHP-FPM
B->>N: HTTP request
alt Nginx自身で処理
N-->>B: 2xx / 4xx など
else upstreamへ転送
N->>U: proxy_pass / fastcgi_pass
U-->>N: response または失敗
N-->>B: HTTP response
end
Even for the same 404, a 404 returned by Nginx’s static file lookup requires checking different places than a 404 returned by an upstream application. Therefore, the first step is to confirm “who generated the response.”
Don’t Just Look at the URL for a 404
For a 404, check the following in order:
Is the path requested by the browser as expected?
Where is Nginx’s
locationrouting the request?If it is a static file, is the relationship between the actual file and root/alias correct?
If it is an upstream application, does that route actually exist?
Note that according to RFC 9110, a 404 can also be used when the server does not wish to reveal the existence of a target resource, so you cannot definitively conclude “the physical file does not exist” based on a 404 alone.
Check the Upstream Boundary for a 502
Nginx’s proxy_pass and fastcgi_pass are used in configurations where another server or a FastCGI process exists behind Nginx. If a 502 occurs, check the following, for example:
Are the upstream host, port, or Unix socket correct?
Is the upstream process running?
Are the permissions and path configured correctly for Nginx to connect?
Is it supposed to communicate via HTTP or FastCGI?
Do the error logs contain specific failures encountered when connecting to the upstream?
The boundary can break not only because “the upstream is down,” but also due to misconfigured connection destinations or socket permissions.
Find the “Slow Spot” for a 504
A 504 indicates a state where the gateway or proxy could not receive an upstream response within the allotted time. Before simply increasing the timeout value, check whether processing is hanging on the upstream side or if waiting for an external API or database is taking too long.
Hiding symptoms solely by extending timeouts can delay the discovery of the root cause.
Try It Now: Actually Trigger a 404 on Localhost
Instead of just reading about it, let’s observe a 404 on your own PC. Without changing the Nginx configuration, launch a simple Python HTTP server using just 127.0.0.1.
Terminal 1:
python3 -m http.server 8000 --bind 127.0.0.1
Terminal 2:
curl -i http://127.0.0.1:8000/not-found
Since the file not-found has not been created, the simple HTTP server returns 404 File not found. This safely confirms that “a 404 is actually returned as an HTTP response.”
When troubleshooting live sites, you may sometimes want to view only the status, headers, and connection target without outputting the entire body. With the GitHub sample, you can use it like this:
./check-http-status.sh https://example.com/
This primarily displays the response headers, HTTP status, remote IP, and total time. Replace the URL with your target for verification.
You do not need to intentionally break production Nginx upstream configurations to learn about 502 or 504. It is safer to first observe the status, moving on to the upstream connection boundary for 502 errors, and upstream processing time or timeouts for 504 errors.
Initial Triage
flowchart TD
A[HTTPエラーを確認] --> B{404?}
B -- はい --> C[URL / location / route / fileを確認]
B -- いいえ --> D{502?}
D -- はい --> E[upstream接続・socket・protocol・logを確認]
D -- いいえ --> F{504?}
F -- はい --> G[upstream処理時間・timeout・依存先を確認]
F -- いいえ --> H[別のstatus定義へ]
