Skip to content

next-intl bare / (no cookie, no Accept-Language) drops the response (000) + leaks the request → server death #6479

Description

@proggeramlug

Summary

A bare GET / to a next-intl app (no locale prefix) returns no response under perry (curl exit 28 / 000) where Node returns 307. It's deterministic, and each hit leaks a request/connection so that ~8 of them wedge the whole server.

Deterministic trigger (isolated)

Same standalone server (gscmaster, Next 16.1.1 + next-intl), single-threaded, warm:

request perry node
/en (explicit locale) 307 307
/ + Cookie: NEXT_LOCALE=de 307 307
/ + Accept-Language: de 307/de 307/de
/ bare (no cookie, no Accept-Language) 000 307 (→ /, Set-Cookie: NEXT_LOCALE=en)
/ + Accept-Language: en (default locale) 000 307

The failing case is exactly the locale-detection / default path: no cookie and no Accept-Language. The winning cases (/en, /+cookie, /+AL) produce a byte-identical 307+Set-Cookie response — so it is not the response shape, redirect-to-self, absolute Location, or cookie (a minimal res.writeHead(307,{Location,Set-Cookie}); res.end(body) server handles all of those correctly under perry).

Localization

.next/server/chunks/[root-of-the-server]__…._.js middleware does:

new Negotiator({ headers: { "accept-language": e.get("accept-language") || void 0 } }).languages()

When Accept-Language is absent this passes undefined to Negotiator (the default-locale branch). On that path the async middleware() promise never settles under perry: no response is written (res.end() never called → the response oneshot is dropped → 000), and no error is logged. Each drop leaks the pending request; ~8 kill the server. A single hit fails but the server survives.

Headers.get("accept-language") for a missing header correctly returns null, and null || undefined === undefined (verified). So the drop is downstream — a lost async continuation in the default-locale middleware path (same class as #5989 "dynamic RSC render evaporates" and the streaming-race #6477), not the header read.

Impact

Any next-intl (or middleware-locale-detecting) app: the bare / root — the entry point — hangs for a client that sends no Accept-Language, and repeated hits take the server down.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions