AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Next/Image Optimizer Returns 500 Instead Of 502 When Upstream Fetch Rejects (DNS Failure, Connection Refused, TLS Error)

In Next.js 16.x, the image optimizer's fetchExternalImage rethrows raw fetch errors, causing a 500 Internal Server Error for upstream DNS failures, connection refusals, and TLS handshake errors. The expected behavior is a client-visible upstream error status (502), consistent with other upstream failure handling in the optimizer.

mediumConfidence 95%Next.jsAffected V16.3.0Affected V16.3.4Affected V16.4.0-Canary.26

Origin Analysis

The fetchExternalImage function catches a rejected fetch to normalize TimeoutError into an ImageError(504), but rethrows any other Error unchanged. The image optimizer route handler only maps known ImageError instances to their status codes; an unknown Error falls through to the generic 500 handler, producing a stack trace and misleading server error signal.
1. Clone the repro repository (next@16.3.4 pinned) and run `npm install`. 2. Configure `images.remotePatterns` to allow `does-not-resolve.example.invalid` in `next.config.ts`. 3. In `app/page.tsx`, render an `<Image>` from that host. 4. Run `npm run build && npm start`. 5. Request `curl -i 'http://localhost:3000/_next/image?url=https%3A%2F%2Fdoes-not-resolve.example.invalid%2Fa.jpg&w=640&q=75'`. 6. Observe `500 Internal Server Error` and server log `[TypeError: fetch failed]` with `getaddrinfo ENOTFOUND`.

Fixing Code Block

--- a/packages/next/src/server/image-optimizer.ts +++ b/packages/next/src/server/image-optimizer.ts @@ -145,7 +145,7 @@ if (err.name === 'TimeoutError') { throw new ImageError(504, '"url" parameter is valid but upstream response timed out') } - throw err + throw new ImageError(502, '"url" parameter is valid but upstream request failed') }
Replace the raw rethrow with a throw of ImageError(502). This aligns the rejected fetch path with the existing timeout and non-2xx handling, ensuring the route returns a proper 502 Bad Gateway and no raw stack trace is logged.

Edge Case Audit

Changing from 500 to 502 could affect monitoring dashboards or alerting rules that were tuned to treat 500 as an application fault. Roll back by reverting the one-line change if clients rely on the previous status. Validate that the client `onError` logic still handles 502 as expected and that no other code path catches generic Error from this function.

Ecosystem Topology