{"record":{"id":"b205d4f2907b4a16","repo":"docker/compose","slug":"invalid-subnet-w","errorCode":null,"errorMessage":"invalid subnet: %w","messagePattern":"invalid subnet: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/compose/create.go","lineNumber":1532,"sourceCode":"\t\ts.events.On(errorEvent(eventName, err.Error()))\n\t\treturn err\n\t}\n\ts.events.On(createdEvent(eventName))\n\treturn nil\n}\n\nfunc parseIPAMPool(pool *types.IPAMPool) (network.IPAMConfig, error) {\n\tvar (\n\t\terr        error\n\t\tsubNet     netip.Prefix\n\t\tipRange    netip.Prefix\n\t\tgateway    netip.Addr\n\t\tauxAddress map[string]netip.Addr\n\t)\n\tif pool.Subnet != \"\" {\n\t\tsubNet, err = netip.ParsePrefix(pool.Subnet)\n\t\tif err != nil {\n\t\t\treturn network.IPAMConfig{}, fmt.Errorf(\"invalid subnet: %w\", err)\n\t\t}\n\t}\n\tif pool.IPRange != \"\" {\n\t\tipRange, err = netip.ParsePrefix(pool.IPRange)\n\t\tif err != nil {\n\t\t\treturn network.IPAMConfig{}, fmt.Errorf(\"invalid ip-range: %w\", err)\n\t\t}\n\t}\n\tif pool.Gateway != \"\" {\n\t\tgateway, err = netip.ParseAddr(pool.Gateway)\n\t\tif err != nil {\n\t\t\treturn network.IPAMConfig{}, fmt.Errorf(\"invalid gateway address: %w\", err)\n\t\t}\n\t}\n\tif len(pool.AuxiliaryAddresses) > 0 {\n\t\tauxAddress = make(map[string]netip.Addr, len(pool.AuxiliaryAddresses))\n\t\tfor auxName, addr := range pool.AuxiliaryAddresses {\n\t\t\tauxAddr, err := netip.ParseAddr(addr)","sourceCodeStart":1514,"sourceCodeEnd":1550,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/compose/create.go#L1514-L1550","documentation":"An IPAM pool 'subnet' string in the compose network config could not be parsed as an CIDR prefix (netip.ParsePrefix). It wraps the parser error, so the message includes the exact position/reason (e.g. missing netmask, host bits set, malformed octets).","triggerScenarios":"networks: x: {ipam: {config: [{subnet: 172.16.0.1}]}} — any subnet value that is not a valid CIDR like 172.16.0.0/16; also host bits set (172.16.0.1/16) which netip rejects.","commonSituations":"Using a gateway address as the subnet; forgetting the /prefix; typo'd IPv6 subnet; copying a range ('172.16.0.0-172.16.0.255') which is not CIDR syntax.","solutions":["Use full CIDR with network address: 172.16.0.0/16, not .1","For IPv6 include the prefix: fd00:dead:beef::/64","If you meant a subset of a subnet, use ip_range instead","Validate with a quick parse before running compose"],"exampleFix":"# before\nsubnet: 172.16.0.1/16\n# after\nsubnet: 172.16.0.0/16\n# gateway goes in its own field:\ngateway: 172.16.0.1","handlingStrategy":"validation","validationCode":"for _, pool := range net.IPAM.Config {\n    if pool.Subnet != \"\" {\n        if _, err := netip.ParsePrefix(pool.Subnet); err != nil {\n            return fmt.Errorf(\"fix subnet %q: %w\", pool.Subnet, err)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write subnets as network-address/prefix","Generate YAML programmatically with a CIDR type, not strings","Validate compose files in CI with docker compose config"],"tags":["network","ipam","validation","cidr"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}