Skip to content

fix(core): avoid keep-alive socket reuse during OAuth token exchange#28103

Open
ryium wants to merge 1 commit into
google-gemini:mainfrom
ryium:fix/oauth-keepalive-premature-close
Open

fix(core): avoid keep-alive socket reuse during OAuth token exchange#28103
ryium wants to merge 1 commit into
google-gemini:mainfrom
ryium:fix/oauth-keepalive-premature-close

Conversation

@ryium

@ryium ryium commented Jun 23, 2026

Copy link
Copy Markdown

Summary

OAuth "Sign in with Google" fails with
Failed to exchange authorization code for tokens: ... Premature close on the
three Node.js releases that shipped the June 2026 security fix for
CVE-2026-48931 ("fix response queue poisoning in http.Agent"):
24.17.0, 22.23.0, and 26.3.1. That fix regressed keep-alive socket reuse,
making node-fetch throw a spurious ERR_STREAM_PREMATURE_CLOSE when a pooled
socket is reused, breaking login. Each release is fixed in its next version
(24.18.0 / 22.23.1 / 26.x), but users pinned to an affected release (e.g. a
node:24.17.0 base image) still hit it. This change makes the OAuth token
exchange use a fresh (non-keep-alive) connection so sign-in works regardless of
the running Node version.

Details

The token exchange runs through google-auth-librarygaxiosnode-fetch,
which uses Node's global keep-alive agent. The CVE-2026-48931 fix attaches a
guard listener to idle pooled sockets; on reuse, node-fetch@2 misreads this as
a premature close and throws ERR_STREAM_PREMATURE_CLOSE (see nodejs/node#63989).
The Node-side regression is fixed by nodejs/node#64004, shipped in
24.18.0 / 22.23.1 / 26.x.

Affected vs. unaffected (verified empirically with mise, node-fetch@2 over a
keep-alive agent reusing a single socket):

Node Result
24.17.0, 22.23.0 ERR_STREAM_PREMATURE_CLOSE on first reuse
24.18.0, 22.23.1
24.13.0, 20.17.0 (pre-fix / never patched)

Fix: in initOauthClient (packages/core/src/code_assist/oauth2.ts), pass
new https.Agent({ keepAlive: false }) to the OAuth2Client transporter when no
proxy is configured, forcing a fresh connection per request and sidestepping the
regression on any Node version. It is harmless on fixed/unaffected versions
because the OAuth token exchange is a one-shot request that gains nothing from
keep-alive. The proxy path is left unchanged, since supplying our own agent would
make gaxios ignore the configured proxy. Because the same client also backs the
Code Assist API calls, the whole code-assist flow benefits.

Related Issues

How to Validate

  1. Use an affected release: Node.js 24.17.0, 22.23.0, or 26.3.1
    (node -v). On 24.18.0 / 22.23.1 / 26.x the bug no longer reproduces without
    this change.
  2. Build core: npm run generate && npm run build --workspace=@google/gemini-cli-core.
  3. Run the unit tests: npx vitest run packages/core/src/code_assist/oauth2.test.ts
    • New cases assert the OAuth transporter uses a keepAlive: false agent when
      no proxy is set, and keeps proxy (no custom agent) when a proxy is set.
  4. End-to-end: launch the CLI and choose "Login with Google"; the
    authorization-code → token exchange completes instead of failing with
    "Premature close".
  5. Edge case (proxy): with HTTPS_PROXY set / --proxy configured, login still
    routes through the proxy as before.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@ryium ryium requested a review from a team as a code owner June 23, 2026 02:22
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical regression in Node.js versions 24.17.0 and later, where socket reuse in the global http.Agent causes OAuth token exchange failures. By forcing a fresh connection per request via a custom https.Agent when no proxy is configured, the fix restores login functionality for users on newer Node.js versions while maintaining support for existing proxy environments.

Highlights

  • OAuth Connection Fix: Implemented a workaround for a Node.js regression (>= 24.17.0) that caused 'ERR_STREAM_PREMATURE_CLOSE' errors during OAuth token exchange by disabling keep-alive for non-proxy connections.
  • Proxy Compatibility: Ensured that existing proxy configurations remain functional by only applying the custom agent when no proxy is detected, preventing gaxios from ignoring proxy settings.
  • Regression Testing: Added unit tests to verify that the OAuth transporter correctly disables keep-alive when no proxy is present and preserves proxy settings when configured.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions github-actions Bot added the size/m A medium sized PR label Jun 23, 2026
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

📊 PR Size: size/M

  • Lines changed: 87
  • Additions: +84
  • Deletions: -3
  • Files changed: 2

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a workaround for a Node.js regression (nodejs/node#63989) where socket reuse in http.Agent causes node-fetch to throw a spurious ERR_STREAM_PREMATURE_CLOSE error during OAuth token exchange. To resolve this, HTTP keep-alive is disabled by configuring a custom https.Agent with keepAlive: false when initializing the OAuth2Client, unless a proxy is configured. Corresponding unit tests have been added to verify this behavior under both proxy and non-proxy configurations. There are no review comments, so I have no feedback to provide.

@gemini-cli gemini-cli Bot added priority/p2 Important but can be addressed in a future release. area/security Issues related to security labels Jun 23, 2026
@galdawave galdawave requested a review from a team June 23, 2026 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security Issues related to security priority/p2 Important but can be addressed in a future release. size/m A medium sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant