Skip to content

http: node-fetch throws ERR_STREAM_PREMATURE_CLOSE on keep-alive socket closures after latest security releases #63989

Description

@tobalsgithub

Version

v24.17.0

Platform

Reproduced on Linux x64 (Cloud Run / gVisor, Debian 12). A second, independent
  report is on Windows 11 x64 (see firebase-tools #10681 below), so this appears
  to be platform-independent and runtime-version-driven.

Subsystem

http / http.Agent (keep-alive socket reuse)

What steps will reproduce the bug?

I don't yet have a reduced standalone repro, but the behavior change is sharply bisected and reproduces across two independent code paths plus a second reporter:

Both paths run through gaxios@6.7.1node-fetch@2.7.0 → core node:http with a keep-alive http.Agent, making requests to *.googleapis.com:

  1. googleapis@144 Drive files.list (background polling loop, long-lived process)
  2. @google-cloud/storage@7.14.0 v4 signed-URL signing via google-auth-library@9.15.0
    GoogleAuth.signBlobhttps://iamcredentials.googleapis.com/.../:signBlob

Both began failing immediately on a deploy whose only material change was the Node runtime moving from 24.16.0 → 24.17.0 (a floating node:24-slim base image picked up the same-day 24.17.0 release). No dependency versions changed. Pinning the image back to node:24.16.0-slim fully resolves both.

A likely minimal-repro shape (from the related node-fetch issue below) is a keep-alive https.Agent ({ keepAlive: true, maxSockets: N }) issuing more than N sequential/concurrent requests to a chunked or gzip-encoded HTTPS endpoint. I'm happy to invest in a self-contained reproduction if that would help — wanted to file the bisect promptly given the blast radius.

How often does it reproduce? Is there a required condition?

Reliably under load on 24.17.0; never on 24.16.0. Appears tied to keep-alive socket reuse — the failure is a premature close on a reused pooled socket.

What is the expected behavior? Why is that the expected behavior?

Keep-alive pooled HTTP requests that complete normally on 24.16.0 should continue to complete on 24.17.0 without the response body being reported as prematurely closed.

What do you see instead?

FetchError: Invalid response body while trying to fetch https://www.googleapis.com/drive/v3/files?...: Premature close code: ERR_STREAM_PREMATURE_CLOSE

and on the signing path:

  SigningError: Invalid response body while trying to fetch
  https://iamcredentials.googleapis.com/.../:signBlob: Premature close
    gaxios@6.7.1/gaxios.ts:157
    google-auth-library@9.15.0 GoogleAuth.signBlob

Additional information

  • Suspected cause: the 24.17.0 changelog entry "http: fix response queue poisoning in http.Agent" (plus the TLS/SNI changes) — anything altering keep-alive socket reuse timing is a candidate.
  • Independent same-day report (different OS, different Google tool): Firebase login issue firebase/firebase-tools#10681FetchError ... Premature close on https://accounts.google.com/o/oauth2/token, Node v24.17.0, Windows 11.
  • Latent library-side bug being exposed: Malformed chunked response detector creates false-positive ‘premature close’ errors when HTTP Agent involved node-fetch/node-fetch#1767 ("Malformed chunked response detector creates false-positive 'premature close' errors when HTTP Agent involved"). It's plausible 24.17.0 is correctly surfacing a long-standing node-fetch defect rather than itself being wrong — but since the observable trigger is the runtime bump and node-fetch@2 is effectively unmaintained, confirmation of whether this is intended/expected behavior at the http.Agent level (vs. a fix-forward in 24.17.x) would help a large slice of the Google-API-client ecosystem decide how to respond.
  • The whole googleapis / @Google-Cloud / google-auth-library stack still depends transitively on gaxios@6node-fetch@2, so the affected surface is broad.

Metadata

Metadata

Assignees

Labels

confirmed-bugIssues with confirmed bugs.httpIssues or PRs related to the http subsystem.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions