hashicorp/nomad · error

invalid bridge_network_subnet: not an IPv4 address: %s

Error message

invalid bridge_network_subnet: not an IPv4 address: %s

What it means

After net.ParseCIDR succeeds, convertClientConfig additionally requires bridge_network_subnet to be IPv4. If the parsed address has no IPv4 representation (ip.To4() == nil), i.e. an IPv6 CIDR was supplied, this error is returned and agent startup/reload fails.

Source

Thrown at command/agent/agent.go:1117

	// Setup the ACLs
	conf.ACLEnabled = agentConfig.ACL.Enabled
	conf.ACLTokenTTL = agentConfig.ACL.TokenTTL
	conf.ACLPolicyTTL = agentConfig.ACL.PolicyTTL
	conf.ACLRoleTTL = agentConfig.ACL.RoleTTL

	// Setup networking configuration
	conf.CNIPath = agentConfig.Client.CNIPath
	conf.CNIConfigDir = agentConfig.Client.CNIConfigDir
	conf.BridgeNetworkName = agentConfig.Client.BridgeNetworkName
	ipv4Subnet := agentConfig.Client.BridgeNetworkSubnet
	if ipv4Subnet != "" {
		ip, _, err := net.ParseCIDR(ipv4Subnet)
		if err != nil {
			return nil, fmt.Errorf("invalid bridge_network_subnet: %w", err)
		}
		// it's a valid IP, so now make sure it is ipv4
		if ip.To4() == nil {
			return nil, fmt.Errorf("invalid bridge_network_subnet: not an IPv4 address: %s", ipv4Subnet)
		}
		conf.BridgeNetworkAllocSubnet = ipv4Subnet
	}
	ipv6Subnet := agentConfig.Client.BridgeNetworkSubnetIPv6
	if ipv6Subnet != "" {
		ip, _, err := net.ParseCIDR(ipv6Subnet)
		if err != nil {
			return nil, fmt.Errorf("invalid bridge_network_subnet_ipv6: %w", err)
		}
		// it's valid, so now make sure it's *not* ipv4
		if ip.To4() != nil {
			return nil, fmt.Errorf("invalid bridge_network_subnet_ipv6: not an IPv6 address: %s", ipv6Subnet)
		}
		conf.BridgeNetworkAllocSubnetIPv6 = ipv6Subnet
	}
	conf.BridgeNetworkHairpinMode = agentConfig.Client.BridgeNetworkHairpinMode

	for _, hn := range agentConfig.Client.HostNetworks {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Move the IPv6 value to client.bridge_network_subnet_ipv6
  2. Set client.bridge_network_subnet to an IPv4 CIDR, e.g. '172.26.66.0/20'
  3. If only IPv6 networking is desired, remove bridge_network_subnet entirely and configure only the IPv6 field

Example fix

// before
client {
  bridge_network_subnet = "fd00::/64"
}
// after
client {
  bridge_network_subnet = "172.26.66.0/20"
  bridge_network_subnet_ipv6 = "fd00::/64"
}
Defensive patterns

Strategy: validation

Validate before calling

subnet := "172.26.66.0/20"
if ip, _, err := net.ParseCIDR(subnet); err != nil || ip.To4() == nil {
    return fmt.Errorf("bridge_network_subnet must be an IPv4 CIDR")
}

Type guard

func isValidIPv4CIDR(s string) bool {
    ip, _, err := net.ParseCIDR(s)
    return err == nil && ip.To4() != nil
}

Prevention

When it happens

Trigger: Setting client.bridge_network_subnet to an IPv6 CIDR such as 'fd00::/64' or '::1/128'; raised during agent start, clientConfig construction, or handleReload.

Common situations: Users intending to configure IPv6 bridge networking but placing the IPv6 subnet in bridge_network_subnet instead of bridge_network_subnet_ipv6; copy-paste from IPv6 documentation.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/6120f7c7529f49d0. Report an issue: GitHub.