docker/cli · error
invalid IP address in add-host
Error message
invalid IP address in add-host: %q
What it means
Returned by ValidateExtraHost (opts/hosts.go:189) when the IP half of a `--add-host` entry fails ValidateIPAddress. After stripping optional square brackets, the value must parse as an IPv4/IPv6 address via net.ParseIP, unless it is the exact string `host-gateway` (which is special-cased and skips validation). This catches malformed addresses before they reach the daemon.
Solutions
- Use a valid IPv4 (myhost:127.0.0.1) or IPv6 (myhost:::1 / myhost=[::1]).
- If you meant the host's gateway IP, use the literal: myhost:host-gateway.
- Resolve any DNS name to an IP yourself before constructing the entry; the parser does not resolve names.
- Check for stray brackets/whitespace — only fully-wrapped [addr] is unwrapped, partial brackets are left intact and fail.
Example fix
// before
v, err := opts.ValidateExtraHost("db:db.internal")
// after
v, err := opts.ValidateExtraHost("db:10.0.0.5") Defensive patterns
Strategy: validation
Validate before calling
// resolveAddHostIP returns the IP to store, or an error, before ValidateExtraHost.
func resolveAddHostIP(value string) (string, error) {
if value == "host-gateway" {
return value, nil
}
v := strings.Trim(value, "[]")
if ip := net.ParseIP(strings.TrimSpace(v)); ip == nil {
return "", fmt.Errorf("not a valid IP: %q", value)
}
return v, nil
} Try / catch
if _, err := opts.ValidateExtraHost(entry); err != nil {
return fmt.Errorf("invalid extra host %q: %w", entry, err)
} Prevention
- Resolve DNS names to IPs before building add-host strings.
- Use host-gateway literally when you want the host gateway.
- Strip brackets from IPv6 yourself only if you bypass ValidateExtraHost.
When it happens
Trigger: Calling ValidateExtraHost where the value side (after `:` or `=` and bracket stripping) is not a valid IP and is not `host-gateway`, e.g. `myhost:127.0.0`, `myhost:999.999.999.999`, `myhost:example.com`, or `myhost:not-an-ip`.
Common situations: Typing a hostname instead of an IP on the value side, truncated IPv4, wrong IPv6 syntax, or assuming DNS names are accepted (they are not — only IPs or host-gateway).
Related errors
- bad format for add-host
- invalid bind address format
- invalid proto, expected
- invalid proto, expected tcp
- IP address is not correctly formatted
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/bd02e8586a5a2683.
Report an issue: GitHub.
Appendix: source
Thrown at opts/hosts.go:189
// '--add-host'. So, it'll split at the first colon and generate a strange error
// message.)
if !ok || k == "" || strings.Contains(k, ":") {
return "", fmt.Errorf("bad format for add-host: %q", val)
}
// Skip IPaddr validation for "host-gateway" string
if v != hostGatewayName {
// If the address is enclosed in square brackets, extract it (for IPv6, but
// permit it for IPv4 as well; we don't know the address family here, but it's
// unambiguous).
if len(v) > 2 && v[0] == '[' && v[len(v)-1] == ']' {
v = v[1 : len(v)-1]
}
// ValidateIPAddress returns the address in canonical form (for example,
// 0:0:0:0:0:0:0:1 -> ::1). But, stick with the original form, to avoid
// surprising a user who's expecting to see the address they supplied in the
// output of 'docker inspect' or '/etc/hosts'.
if _, err := ValidateIPAddress(v); err != nil {
return "", fmt.Errorf("invalid IP address in add-host: %q", v)
}
}
// This result is passed directly to the API, the daemon doesn't accept the '='
// separator or an address enclosed in brackets. So, construct something it can
// understand.
return k + ":" + v, nil
}
View on GitHub (pinned to 4f84911bfe)