Skip to content

Next.js 16 on Node 27: null-prototype HTTP/1 request headers break headers.hasOwnProperty() #76

Open

Description

@Ethan-Arrowood

Problem

nodejs/node#62900 makes IncomingMessage.headers (and trailers) a null-prototype object on HTTP/1, which HTTP/2 headers already are. It is semver-major and landed on Node main only, so it ships in Node 27. Node's release schedule puts Node 27 on 2027-04-22. Node 22, 24 and 26 are not affected.

Next.js 16 calls headers.hasOwnProperty(PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER) in checkIsOnDemandRevalidate (next/dist/server/api-utils). That call still exists on canary (packages/next/src/server/api-utils/index.ts, checked at 16.5.0-canary.18). On null-prototype headers it fails with the same headers.hasOwnProperty is not a function 500 that #73 fixed for HTTP/2. Next 14 and 15 use headers.has() there, so the known call site affects Next 16 and later. Next's server bundles are minified, so other callers can't be ruled out.

In this plugin, adaptHttp2ForNext in src/http2Compat.ts returns early for anything that isn't an Http2ServerRequest. On Node 27, every Next 16 page served over HTTP/1 would therefore 500. The leaves HTTP/1 requests untouched test in src/http2Compat.test.ts also asserts that HTTP/1 headers use Object.prototype, so it will fail once CI adds Node 27.

Options

  • Upstream: Next.js should use Object.hasOwn(headers, …). Check vercel/next.js for an existing report and file one if there isn't one. If Next fixes it, only the Next 16 releases from before the fix need the plugin's help.
  • Plugin: when HTTP/1 request headers have a null prototype, hand Next.js the same Object.prototype copy the HTTP/2 path already builds. Update the HTTP/1 test to assert behaviour rather than the prototype.

Done when Next 16 serves pages over HTTP/1 through the plugin on a Node build that includes nodejs/node#62900 (a Node 27 nightly or RC), with a test that covers it.

Refs #73.

🤖 Generated by Claude Opus 5.5; posted via @Ethan-Arrowood.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    P2

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions