juanfont/headscale · error

no IPAM config found in network: %s

Error message

no IPAM config found in network: %s

What it means

Returned by Scenario.SubnetOfNetwork(name) when the Docker network exists but its IPAM config list is empty, so no subnet CIDR can be derived. The network object came back from Docker without an assigned address pool.

Source

Thrown at integration/scenario.go:339

}

func (s *Scenario) Network(name string) (*dockertest.Network, error) {
	net, ok := s.networks[s.prefixedNetworkName(name)]
	if !ok {
		return nil, fmt.Errorf("no network named: %s", name) //nolint:err113
	}

	return net, nil
}

func (s *Scenario) SubnetOfNetwork(name string) (*netip.Prefix, error) {
	net, ok := s.networks[s.prefixedNetworkName(name)]
	if !ok {
		return nil, fmt.Errorf("no network named: %s", name) //nolint:err113
	}

	if len(net.Network.IPAM.Config) == 0 {
		return nil, fmt.Errorf("no IPAM config found in network: %s", name) //nolint:err113
	}

	pref, err := netip.ParsePrefix(net.Network.IPAM.Config[0].Subnet)
	if err != nil {
		return nil, err
	}

	return &pref, nil
}

func (s *Scenario) Services(name string) ([]*dockertest.Resource, error) {
	res, ok := s.extraServices[s.prefixedNetworkName(name)]
	if !ok {
		return nil, fmt.Errorf("no network named: %s", name) //nolint:err113
	}

	return res, nil
}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Create the network with an explicit subnet: s.AddNetworkWithSubnet(name, "172.10.0.0/24")
  2. Inspect the network with `docker network inspect <name>` to confirm IPAM config exists before relying on SubnetOfNetwork
  3. If the network is pre-existing, recreate it through the scenario so IPAM is guaranteed populated

Example fix

// before
_, err := scenario.AddNetwork("mynet")
// ...
pref, err := scenario.SubnetOfNetwork("mynet")

// after
_, err := scenario.AddNetworkWithSubnet("mynet", "172.10.0.0/24")
// ...
pref, err := scenario.SubnetOfNetwork("mynet")
Defensive patterns

Strategy: validation

Validate before calling

// Guard: only expect IPAM data when the subnet was declared explicitly
const subnet = "172.10.0.0/24"
if _, err := scenario.AddNetworkWithSubnet(name, subnet); err != nil {
    t.Fatal(err)
}

Try / catch

pref, err := scenario.SubnetOfNetwork(name)
if err != nil {
    t.Fatalf("network %q has no IPAM config (was it created without a subnet?): %v", name, err)
}

Prevention

When it happens

Trigger: Calling SubnetOfNetwork on a network that was created without an explicit subnet and whose IPAM config was not populated, or on an externally created network attached to the scenario lacking IPAM metadata.

Common situations: Using AddNetwork (empty subnet) then immediately asking for the subnet; Docker driver (e.g. ipvlan/macvlan or pre-created networks) that does not populate Network.Network.IPAM.Config; inspecting a network created by another tool.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/11670ec1a7c19d19. Report an issue: GitHub.