Unable to set an ipv6 address for a service
- Dominant language
- Go
- Stars
- 30.1k
- Forks
- 4.6k
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 39
Description
#### Overview of the Issue
I want to create a service with nomad+consul on an ipv6-only machine, which doesn't work.
---
#### Reproduction Steps
According to the documentation, one needs to add this to a service config in order to assign an ipv6 to the public interface of a system:
```default
tagged_addresses {
wan_ipv6 = "..."
}
```
When I just add an ipv6 address:
```default
tagged_addresses {
wan_ipv6 = "2a01:4f8:c2c:cd3c:fefe::beef"
}
```
Then the following error occurs:
```default
2026-01-22T07:40:31.578+0100 [ERROR] client.alloc_runner: prerun failed: alloc_id=b93350ec-8196-398f-7d32-db946efddc87 error="pre-run hook \"group_services\" failed: error parsing address \"2a01:4f8:c2c:cd3c:fefe::beef\": address 2a01:4f8:c2c:cd3c:fefe::beef: too many colons in address
```
Then I looked up the code and saw, that it calls `net.SplitHostPort()` for whatever strange reason, which expects for ipv6 something like `[ip]:port`. Since the port cannot really be a part of the `wan_ipv6` field, I tried:
```default
tagged_addresses {
wan_ipv6 = "[2a01:4f8:c2c:cd3c:fefe::beef]"
}
```
which yields this error:
```default
2026-01-22T07:47:24.279+0100 [INFO] client.alloc_runner.task_runner: Task event: alloc_id=f3a7eecb-9a3b-1904-ec4a-950dec17db91 task=nginx-task type="Setup Failure" msg="failed to setup alloc: pre-run hook \"group_services\" failed: error parsing address \"[2a01:4f8:c2c:cd3c:fefe::beef]\": not an IP address" failed=true
```
Ok, so the port seems to be required, then I tried:
```default
tagged_addresses {
wan_ipv6 = "[2a01:4f8:c2c:cd3c:fefe::beef]:80"
}
```
Now the service comes up without any errors, it's also reachable via its dynamic ipv6 address, but not from the one I specified.
The address is also not configured on the machine, which is something I'd expect from Consul. What use would it be for otherwise? However, I tried to add an alias to the public interface like this:
```console
oot@podmaster: # ifconfig bridge0 inet6 2a01:4f8:c2c:cd3c:fefe::beef/128 alias
root@podmaster: # ifconfig bridge0
bridge0: flags=1008843 metric 0 mtu 1500
options=0
ether 92:00:06:fa:8f:0c
inet 10.89.1.1 netmask 0xffffff00 broadcast 10.89.1.255
inet6 2a01:4f8:c2c:cd3c::1 prefixlen 80
inet6 fe80::9000:6ff:fefa:8f0c%bridge0 prefixlen 64 scopeid 0x3
inet6 2a01:4f8:c2c:cd3c:fefe::1 prefixlen 80
inet6 2a01:4f8:c2c:cd3c:fefe::beef prefixlen 128
[..]
```
But this didn't make any difference.
Unfortunately it is also impossible to inspect running services. One can only list services but not get any details about them.
### Consul info for both Client and Server
```default
# consul info
agent:
check_monitors = 0
check_ttls = 0
checks = 5
services = 5
build:
prerelease =
revision = 3261d11
version = 1.21.5
version_metadata =
consul:
acl = enabled
bootstrap = true
known_datacenters = 1
leader = true
leader_addr = [2a01:4f8:c2c:cd3c::1]:8300
server = true
raft:
applied_index = 6407
commit_index = 6407
fsm_pending = 0
last_contact = 0
last_log_index = 6407
last_log_term = 4
last_snapshot_index = 0
last_snapshot_term = 0
latest_configuration = [{Suffrage:Voter ID:7b9ad78f-d64b-c73f-9d0b-bb7631fb05e3 Address:[2a01:4f8:c2c:cd3c::1]:8300}]
latest_configuration_index = 0
num_peers = 0
protocol_version = 3
protocol_version_max = 3
protocol_version_min = 0
snapshot_version_max = 1
snapshot_version_min = 0
state = Leader
term = 4
runtime:
arch = amd64
cpu_count = 2
goroutines = 197
max_procs = 2
os = freebsd
version = go1.25.0
serf_lan:
coordinate_resets = 0
encrypted = false
event_queue = 1
event_time = 4
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 1
members = 1
query_queue = 0
query_time = 1
serf_wan:
coordinate_resets = 0
encrypted = false
event_queue = 0
event_time = 1
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 1
members = 1
query_queue = 0
query_time = 1
# config
datacenter = "dc1"
data_dir = "/var/db/consul"
bind_addr= "2a01:4f8:c2c:cd3c::1"
acl {
enabled = true
default_policy = "deny"
}
server = true
bootstrap_expect = 1
```
That's all I have, theres just 1 instance on 1 machine.
### Operating system and Environment details
```default
OS: FreeBSD 14.3-RELEASE-p7
Consul: Consul v1.21.5, Revision 3261d11, Build Date 2025-09-25T08:51:49Z
Nomad: v1.11.1
nomad-driver-podman: 0.6.3_3
```
I also attached the spec of the running podman container.
[2c8fc20ba5e2.json](https://github.com/user-attachments/files/24788121/2c8fc20ba5e2.json)
Contributor guide
Research direction
Start by reproducing the IPv6 service configuration on the reported FreeBSD and Consul/Nomad versions, then trace the tagged_addresses handling where net.SplitHostPort() is called. Compare the behavior for bare IPv6 addresses and bracketed host-port values; done means a configured wan_ipv6 address is accepted and used as the service address without requiring a port.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100