Skip to content

fix: bracket IPv6 hostnames in WebSocket URLs (#1569) - #2081

Open
kmitchel wants to merge 2 commits into
mqttjs:mainfrom
kmitchel:fix/issue-1569-ipv6-ws-url
Open

kmitchel wants to merge 2 commits into
mqttjs:mainfrom
kmitchel:fix/issue-1569-ipv6-ws-url

Conversation

@kmitchel

@kmitchel kmitchel commented Oct 17, 2026 •

Copy link
Copy Markdown

Fixes #1569

Problem

When connecting to a WebSocket URL with an IPv6 address such as ws://[::1]:8883, url.parse() in src/lib/connect/index.ts strips the square brackets from the hostname (hostname: '::1').

Downstream in ws.ts (as well as ali.ts and wx.ts), buildUrl() reconstructed the URL using ${opts.protocol}://${opts.hostname}:${opts.port}${opts.path}, yielding ws://::1:8883/. Because RFC 3986 and WHATWG URL standards require IPv6 hostnames in URLs to be enclosed in square brackets, passing this string to new WebSocket() or new URL() immediately threw:

TypeError [ERR_INVALID_URL]: Invalid URL: ws://::1:8883/

This also affected connections using options objects with IPv6 addresses (e.g. { host: '::1', port: 8883, protocol: 'ws' }).

Solution

  • Added a formatUrlHost helper function in src/lib/shared.ts that ensures unbracketed IPv6 hostnames (containing : without leading/trailing brackets) are enclosed in [...] when constructing URL strings.
  • Updated buildUrl in src/lib/connect/ws.ts, src/lib/connect/ali.ts, and src/lib/connect/wx.ts to use formatUrlHost.
  • Preserved raw unbracketed hostnames for socket-based connections (net.connect, tls.connect) where unbracketed IPs are expected.

Testing

  • Added unit tests in test/node/mqtt.ts validating:
    1. Connecting via IPv6 WebSocket URL string (ws://[::1]:8883).
    2. Connecting via options object with IPv6 host ({ host: '::1', port: 8883, protocol: 'ws' }).
  • Verified npm run build and eslint pass cleanly.

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.

When connecting ws://[::1]:8883, an error is thrown - Uncaught TypeError TypeError [ERR_INVALID_URL]: Invalid URL

1 participant