Visitar URL original
fix(http2): bracket IPv6 literal hosts in the session authority by b84330808 · Pull Request #11405 · axios/axios · GitHub
Skip to content

fix(http2): bracket IPv6 literal hosts in the session authority - #11405

Draft
b84330808 wants to merge 1 commit into
axios:v1.xfrom
b84330808:claude/funny-gates-5fo2vk
Draft

b84330808 wants to merge 1 commit into
axios:v1.xfrom
b84330808:claude/funny-gates-5fo2vk

Conversation

@b84330808

@b84330808 b84330808 commented Oct 31, 2026 •

Copy link
Copy Markdown

Summary

With httpVersion: 2, a request to an IPv6 literal URL such as https://[::1]:8443/ always fails with AxiosError: Invalid URL (ERR_INVALID_URL) before any connection is attempted.

The HTTP adapter strips the brackets from IPv6 hostnames because http.request() expects the raw address (options.hostname === '::1'). The HTTP/2 transport then builds the session authority from that value, giving https://::1:8443. http2.connect() parses the authority with new URL(), which rejects it.

This PR re-adds the brackets when building the HTTP/2 authority if the hostname is an IPv6 literal. Hostnames and IPv4 addresses produce the same authority string as before, so HTTP/2 session reuse for them is unchanged.

Linked issue

No existing issue. The problem and reproduction are described above.

Changes

  • lib/adapters/http.js: in http2Transport.request(), wrap the hostname in [...] when it contains : (an IPv6 literal) before building the authority passed to http2.connect().
  • tests/unit/adapters/http.test.js: add HTTP2 > should support IPv6 literal hosts. It requests https://[::1]:<port>/ and uses the http2Options.createConnection option to route the socket to the IPv4 test server, so it doesn't need IPv6 on the host. It fails without the fix (TypeError: Invalid URL from http2.connect) and passes with it.
  • PRE_RELEASE_CHANGELOG.md: Bug Fixes entry.

Validation

Run with Claude Code in a Linux x64 container: Node.js v22.22.0, npm 10.9.4, Vitest 4.1.12.

  • npm ci --ignore-scripts: OK.
  • npm run test:vitest:unit -- tests/unit/adapters/http.test.js -t "should support IPv6 literal hosts": fails with the fix reverted (TypeError: Invalid URL), passes with it.
  • npm run lint: OK. npx eslint tests/unit/adapters/http.test.js: 0 errors; the 3 existing "unused eslint-disable directive" warnings are unchanged. npx prettier --check on the changed files: OK.
  • npm run build: OK.
  • npm run test:vitest:unit: 1697 passed, 4 failed. The same 4 fail with this change reverted. Three need network access the container didn't have: regression > 4999 and http > DNS > should handle errors make external requests that the container's proxy blocked with 403, and http > should support IPv6 literal strings needs IPv6 (connect EAFNOSUPPORT ::1). The fourth, fetch > should not use inherited Symbol.iterator for request headers, fails on Node 22.22.0 with or without this change. Unit tests were not run on Node 26.x (the CI version).
  • Browser tests: npm run test:vitest:browser:headless couldn't launch in the container (Playwright 1.64.1's browser builds weren't installed). The same browser test files ran on headless Chromium through a temporary config pointing at the preinstalled Chromium: 27 files, 355 passed, 1 skipped. Firefox and WebKit were not run locally. The changed code is in the Node-only HTTP adapter, which browser builds replace with lib/helpers/null.js.
  • CJS/ESM module and smoke suites: not run, since there are no export, type, or packaging changes.
  • GitHub Actions: pending; to be recorded after the run for the latest commit.

Compatibility and documentation

Patch. Affects only the Node.js HTTP adapter with httpVersion: 2. Not breaking: before this change, every HTTP/2 request to an IPv6 literal host failed. No public API change, so index.d.ts and index.d.cts are unchanged. No PRE_RELEASE_DOCS.md entry is needed, because the documented httpVersion: 2 option now also works for IPv6 URLs.

Limitation: Node.js derives the :authority pseudo-header from the session itself. On Node v22.22.0 it sends IP literals without brackets (::1:8443). This PR doesn't change that.

Checklist

  • Scope, target branch, and linked issue/rationale checked
  • PRE_RELEASE_CHANGELOG.md entry added or updated (or AGENTS.md's automated release-preparation exception explained)
  • Regression tests and relevant negative/platform cases covered (or N/A with reason)
  • Applicable local checks completed, with actual commands and results recorded above (Firefox/WebKit browser tests not run locally)
  • Deferred release docs and ESM/CJS types/tests updated where needed (or N/A with reason)
  • Semver impact stated and intentional breaking changes explained
  • Final diff reviewed for security, unrelated changes, generated artifacts, and test/debug leftovers
  • Latest GitHub Actions status recorded separately from review/security bot results

I used Claude Code to write this change. A maintainer needs to apply the ai-assisted label, since I can't apply labels on this repository.


Summary by cubic

Description

Fixes HTTP/2 requests to IPv6 literal URLs such as https://[::1]:8443/, which previously always failed with ERR_INVALID_URL before any connection was attempted.

  • Summary of changes: When building the HTTP/2 session authority in the Node adapter, wrap the hostname in brackets if it's an IPv6 literal. options.hostname has the brackets stripped for http.request(), but http2.connect() parses the authority as a URL and requires them.
  • Reasoning: The old behavior produced https://::1:8443, which http2.connect() can't parse. Hostnames and IPv4 addresses produce the same authority as before, so HTTP/2 session reuse for them is unchanged.
  • Additional context: Node.js derives the :authority pseudo-header from the session itself and sends IP literals without brackets on current Node versions; this change doesn't affect that.

Docs

No docs update needed—the documented httpVersion: 2 option now also works for IPv6 URLs, so no PRE_RELEASE_DOCS.md entry is required.

Testing

Adds a unit test (should support IPv6 literal hosts) that requests https://[::1]:<port>/ and uses http2Options.createConnection to route the socket to the IPv4 test server, so the test doesn't require IPv6 on the host. It fails with the fix reverted (TypeError: Invalid URL) and passes with it. The full unit suite shows the same 4 pre-existing failures with and without the change (three need network/IPv6 access the CI container lacked; one fails on Node 22.22.0 regardless). Lint, prettier, and build all pass.

Semantic version impact

Patch. Affects only the Node.js HTTP adapter with httpVersion: 2. Not breaking—before this change, every HTTP/2 request to an IPv6 literal host failed. No public API, type, or packaging changes (index.d.ts and index.d.cts are unchanged).

Written for commit aa4d0d9. Summary will update on new commits.

View guided diff

HTTP/2 requests to an IPv6 literal URL such as https://[::1]:8443/ always
failed with ERR_INVALID_URL. The HTTP adapter strips the brackets from
IPv6 hostnames for http.request(), and the HTTP/2 transport built the
session authority from that bare hostname ("https://::1:8443"), which
http2.connect() cannot parse as a URL.

Re-add the brackets when the hostname is an IPv6 literal. Hostnames and
IPv4 addresses produce the same authority as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] No blocking issues were found; the exercised HTTP/2 behavior supports merging the scoped change.

Summary

Fixes HTTP/2 requests to IPv6 literal URLs by restoring brackets when building the session authority.

  • HTTP/2 requests now accept IPv6 literal hosts.

Acknowledged limitations:

  • b84330808 explicitly leaves Node.js’s unbracketed :authority header unchanged.
  • b84330808 reports blocked browser checks, untested Firefox/WebKit and Node 26, and pending GitHub Actions checks. These are disclosed validation limits, not new findings.

T-Rex validation blocked:

  • Evidence upload was unavailable because no artifact-upload mechanism or configured upload destination was exposed. Execution completed; the executed scripts and observed output remain saved locally under trex-artifacts/.

Merge safety: No blocking issues were found in the scoped changes.

Reviews (1) · Last reviewed commit: "fix(http2): bracket IPv6 literal hosts i..." · Reviewed by Greptile

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant