[GH-ISSUE #5601] IPv6 address formatting broken in DNS address construction (missing brackets) #11529

Closed
opened 2026-08-05 01:29:55 -04:00 by saavagebueno · 0 comments
Owner

Originally created by @mango766 on GitHub (Mar 16, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5601

Describe the problem

Several places in the codebase construct DNS server addresses by combining an IP and port using fmt.Sprintf("%s:%d", ip, port). This produces invalid addresses for IPv6 IPs because IPv6 addresses contain colons themselves and need to be wrapped in brackets when combined with a port (e.g., [2606:4700:4700::1111]:53 instead of 2606:4700:4700::1111:53).

This is the same root cause as #4074 — when an IPv6 upstream nameserver is configured, DNS resolution fails with dial udp: address 2606:4700:4700::1111:53: too many colons in address.

Root cause

The following locations use fmt.Sprintf("%s:%d", ip, port) instead of the IPv6-safe net.JoinHostPort():

  1. client/internal/routemanager/dnsinterceptor/handler.go:252 — constructs the upstream DNS address for the DNS interceptor. This is the most critical one as it directly causes DNS query failures with IPv6 upstream servers.
  2. client/internal/dns/service_listener.go:72 — constructs the DNS listener address
  3. client/internal/dns/service_listener.go:189 — constructs the address for port binding probes
  4. client/internal/routemanager/client/client.go:567 — constructs the DNS address for dynamic route handlers

Fix

Replace fmt.Sprintf("%s:%d", ip, port) with net.JoinHostPort(ip.String(), strconv.Itoa(port)) which correctly brackets IPv6 addresses.

Environment

Originally created by @mango766 on GitHub (Mar 16, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5601 **Describe the problem** Several places in the codebase construct DNS server addresses by combining an IP and port using `fmt.Sprintf("%s:%d", ip, port)`. This produces invalid addresses for IPv6 IPs because IPv6 addresses contain colons themselves and need to be wrapped in brackets when combined with a port (e.g., `[2606:4700:4700::1111]:53` instead of `2606:4700:4700::1111:53`). This is the same root cause as #4074 — when an IPv6 upstream nameserver is configured, DNS resolution fails with `dial udp: address 2606:4700:4700::1111:53: too many colons in address`. **Root cause** The following locations use `fmt.Sprintf("%s:%d", ip, port)` instead of the IPv6-safe `net.JoinHostPort()`: 1. `client/internal/routemanager/dnsinterceptor/handler.go:252` — constructs the upstream DNS address for the DNS interceptor. This is the most critical one as it directly causes DNS query failures with IPv6 upstream servers. 2. `client/internal/dns/service_listener.go:72` — constructs the DNS listener address 3. `client/internal/dns/service_listener.go:189` — constructs the address for port binding probes 4. `client/internal/routemanager/client/client.go:567` — constructs the DNS address for dynamic route handlers **Fix** Replace `fmt.Sprintf("%s:%d", ip, port)` with `net.JoinHostPort(ip.String(), strconv.Itoa(port))` which correctly brackets IPv6 addresses. **Environment** - Affects all platforms - Related to #4074
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11529