docker/cli · error
invalid IP address
Error message
invalid IP address: %s
What it means
Raised while converting --default-addr-pool entries to netip.Prefix during 'docker swarm init'. After normalizing a pool's IP to 4 or 16 bytes, netip.AddrFromSlice rejects the slice (e.g. a zero-length IP), which means the supplied CIDR could not yield a valid address.
Solutions
- Use a well-formed CIDR like '10.0.0.0/8' or '192.168.0.0/16'.
- Verify each pool parses with 'ipcalc <cidr>' or 'python3 -c "import ipaddress; ipaddress.ip_network(''CIDR'')"'.
- Drop --default-addr-pool to accept Docker's default address pools.
Example fix
# before docker swarm init --default-addr-pool /24 # after docker swarm init --default-addr-pool 10.0.0.0/8 --subnet-size 24
Defensive patterns
Strategy: validation
Validate before calling
// Validate each CIDR before init
for _, cidr := range pools {
if _, err := netip.ParsePrefix(cidr); err != nil {
return fmt.Errorf("invalid default-addr-pool %q: %w", cidr, err)
}
} Type guard
func validCIDR(s string) bool {
_, err := netip.ParsePrefix(s)
return err == nil
} Prevention
- Pre-validate CIDRs with netip.ParsePrefix in scripts.
- Prefer standard private ranges (10.0.0.0/8, 192.168.0.0/16).
- Avoid degenerate entries like '/24' with no address.
When it happens
Trigger: Passing --default-addr-pool with a malformed CIDR whose IP portion is empty or otherwise unparseable as IPv4/IPv6 (e.g. an all-zero mask with empty IP, or a degenerate IPNet). The loop at init.go:73-88 fails when netip.AddrFromSlice(ip) returns ok==false.
Common situations: Typo in CIDR; passing '/24' without an address; programmatically building net.IPNet values with nil IP; shell quoting stripping the IP portion.
Related errors
- invalid availability
- - specify one with --advertise-addr
- error reading from STDIN: data is empty
- config file is required
- cannot supply extra formatting options to the pretty…
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/37e8b0e7faae52cd.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/swarm/init.go:84
return cmd
}
func runInit(ctx context.Context, dockerCLI command.Cli, flags *pflag.FlagSet, opts initOptions) error {
apiClient := dockerCLI.Client()
// TODO(thaJeztah): change opts.defaultAddrPools a []netip.Prefix; see https://github.com/docker/cli/pull/6545#discussion_r2420361609
defaultAddrPool := make([]netip.Prefix, 0, len(opts.defaultAddrPools))
for _, p := range opts.defaultAddrPools {
if len(p.IP) == 0 {
continue
}
ip := p.IP.To4()
if ip == nil {
ip = p.IP.To16()
}
addr, ok := netip.AddrFromSlice(ip)
if !ok {
return fmt.Errorf("invalid IP address: %s", p.IP)
}
ones, _ := p.Mask.Size()
defaultAddrPool = append(defaultAddrPool, netip.PrefixFrom(addr, ones))
}
var availability swarm.NodeAvailability
if flags.Changed(flagAvailability) {
switch a := swarm.NodeAvailability(strings.ToLower(opts.availability)); a {
case swarm.NodeAvailabilityActive, swarm.NodeAvailabilityPause, swarm.NodeAvailabilityDrain:
availability = a
default:
return fmt.Errorf("invalid availability %q, only active, pause and drain are supported", opts.availability)
}
}
res, err := apiClient.SwarmInit(ctx, client.SwarmInitOptions{
ListenAddr: opts.listenAddr.String(),
AdvertiseAddr: opts.advertiseAddr,
DataPathAddr: opts.dataPathAddr,View on GitHub (pinned to 4f84911bfe)