In Which Layer Do HTTP 404, 502, and 504 Occur? — Troubleshooting from the Nginx and Application Request Path

ネットワーク・RFCカテゴリを表すパンダのイラスト Networking / RFC

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

StatusRFC Meaning (Brief)First Things to Consider
404 Not FoundThe origin server did not find a current representation for the target resource or is not willing to disclose that one existsURL, routing, static files, application-side routes
502 Bad GatewayThe gateway or proxy received an invalid response from the upstream serverUpstream connection destination, protocol, service, socket
504 Gateway TimeoutThe gateway or proxy did not receive a timely response from the upstream serverUpstream 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:

  1. Is the path requested by the browser as expected?

  2. Where is Nginx’s location routing the request?

  3. If it is a static file, is the relationship between the actual file and root/alias correct?

  4. 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定義へ]

GitHub Samples

Official and Primary Information Sources

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
Copied title and URL