Repository navigation
Conversation
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>
Contributor
[Low impact] No blocking issues were found; the exercised HTTP/2 behavior supports merging the scoped change. SummaryFixes HTTP/2 requests to IPv6 literal URLs by restoring brackets when building the session authority.
Acknowledged limitations:
T-Rex validation blocked:
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
With
httpVersion: 2, a request to an IPv6 literal URL such ashttps://[::1]:8443/always fails withAxiosError: 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, givinghttps://::1:8443.http2.connect()parses the authority withnew 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: inhttp2Transport.request(), wrap the hostname in[...]when it contains:(an IPv6 literal) before building the authority passed tohttp2.connect().tests/unit/adapters/http.test.js: addHTTP2 > should support IPv6 literal hosts. It requestshttps://[::1]:<port>/and uses thehttp2Options.createConnectionoption 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 URLfromhttp2.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 --checkon 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 > 4999andhttp > DNS > should handle errorsmake external requests that the container's proxy blocked with 403, andhttp > should support IPv6 literal stringsneeds 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).npm run test:vitest:browser:headlesscouldn'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 withlib/helpers/null.js.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, soindex.d.tsandindex.d.ctsare unchanged. NoPRE_RELEASE_DOCS.mdentry is needed, because the documentedhttpVersion: 2option now also works for IPv6 URLs.Limitation: Node.js derives the
:authoritypseudo-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
PRE_RELEASE_CHANGELOG.mdentry added or updated (or AGENTS.md's automated release-preparation exception explained)I used Claude Code to write this change. A maintainer needs to apply the
ai-assistedlabel, 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 withERR_INVALID_URLbefore any connection was attempted.options.hostnamehas the brackets stripped forhttp.request(), buthttp2.connect()parses the authority as a URL and requires them.https://::1:8443, whichhttp2.connect()can't parse. Hostnames and IPv4 addresses produce the same authority as before, so HTTP/2 session reuse for them is unchanged.:authoritypseudo-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: 2option now also works for IPv6 URLs, so noPRE_RELEASE_DOCS.mdentry is required.Testing
Adds a unit test (
should support IPv6 literal hosts) that requestshttps://[::1]:<port>/and useshttp2Options.createConnectionto 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.tsandindex.d.ctsare unchanged).Written for commit aa4d0d9. Summary will update on new commits.