docker/cli · error

no matching subnet for range

Error message

no matching subnet for range %s

What it means

Returned by `createIPAMConfig` (network/create.go:188-190) when an `--ip-range` value does not fall within ANY declared `--subnet`. Each ip-range must be contained by a subnet so the IPAM model can correlate it; an unmatched range is rejected. The message names the offending range.

Solutions

  1. Ensure every --ip-range is a subset of some declared --subnet.
  2. Add a --subnet that contains the range, or fix the range CIDR.
  3. Check address family consistency (don't mix IPv4 ranges with IPv6 subnets).
  4. Count: there must be at least as many --subnet values as --ip-range values.

Example fix

# before
docker network create --subnet 172.20.0.0/16 --ip-range 192.168.1.0/24 net
# after
docker network create --subnet 172.20.0.0/16 --ip-range 172.20.5.0/24 net
Defensive patterns

Strategy: validation

Validate before calling

// ensure every ip-range is contained by some subnet
for _, r := range ipRanges {
    matched := false
    for _, s := range subnets {
        ok, _ := subnetMatches(s, r.String())
        if ok { matched = true; break }
    }
    if !matched { return fmt.Errorf("ip-range %s not within any --subnet", r) }
}

Try / catch

if err := runCreate(ctx, c, out, options); err != nil {
    if strings.Contains(err.Error(), "no matching subnet for range") {
        return fmt.Errorf("%w — add a --subnet that contains the range", err)
    }
    return err
}

Prevention

When it happens

Trigger: Running `docker network create --subnet 172.20.0.0/16 --ip-range 192.168.1.0/24 net` — the range is in a different network than the subnet.

Common situations: Typo in the range CIDR, forgetting to add the enclosing --subnet, or mismatched address families (IPv6 range with IPv4 subnet).

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/29c709dd74ef7c47. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/network/create.go:189

			ok, err := subnetMatches(s, r.String())
			if err != nil {
				return nil, err
			}
			if !ok {
				continue
			}

			// Using "IsValid" to check if a valid IPRange was already set.
			if iData[s].IPRange.IsValid() {
				return nil, fmt.Errorf("cannot configure multiple ranges (%s, %s) on the same subnet (%s)", r.String(), iData[s].IPRange.String(), s)
			}
			if ipRange, ok := toPrefix(r); ok {
				iData[s].IPRange = ipRange
				match = true
			}
		}
		if !match {
			return nil, fmt.Errorf("no matching subnet for range %s", r.String())
		}
	}

	// Validate and add valid gateways
	for _, g := range options.gateways {
		match := false
		for _, s := range options.subnets {
			ok, err := subnetMatches(s, g.String())
			if err != nil {
				return nil, err
			}
			if !ok {
				continue
			}
			if iData[s].Gateway.IsValid() {
				return nil, fmt.Errorf("cannot configure multiple gateways (%s, %s) for the same subnet (%s)", g, iData[s].Gateway, s)
			}
			d := iData[s]

View on GitHub (pinned to 4f84911bfe)