{"record":{"id":"8b39a6a793f1d071","repo":"cilium/cilium","slug":"prefix-length-must-be-96","errorCode":null,"errorMessage":"Prefix length must be /96","messagePattern":"Prefix length must be /96","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/option/config.go","lineNumber":2160,"sourceCode":"\t\treturn err\n\t}\n\n\tif ones, _ := cidr.Mask.Size(); ones != 64 {\n\t\treturn fmt.Errorf(\"Prefix length must be /64\")\n\t}\n\n\tc.IPv6ClusterAllocCIDRBase = ip.Mask(cidr.Mask).String()\n\n\treturn nil\n}\n\nfunc (c *DaemonConfig) validateIPv6NAT46x64CIDR() error {\n\tparsedPrefix, err := netip.ParsePrefix(c.IPv6NAT46x64CIDR)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif parsedPrefix.Bits() != 96 {\n\t\treturn fmt.Errorf(\"Prefix length must be /96\")\n\t}\n\n\tc.IPv6NAT46x64CIDRBase = parsedPrefix.Masked().Addr()\n\treturn nil\n}\n\nfunc (c *DaemonConfig) validateContainerIPLocalReservedPorts() error {\n\tif c.ContainerIPLocalReservedPorts == \"\" || c.ContainerIPLocalReservedPorts == defaults.ContainerIPLocalReservedPortsAuto {\n\t\treturn nil\n\t}\n\n\tif regexp.MustCompile(`^(\\d+(-\\d+)?)(,\\d+(-\\d+)?)*$`).MatchString(c.ContainerIPLocalReservedPorts) {\n\t\treturn nil\n\t}\n\n\treturn fmt.Errorf(\"Invalid comma separated list of ranges for %s option\", ContainerIPLocalReservedPorts)\n}\n","sourceCodeStart":2142,"sourceCodeEnd":2178,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/option/config.go#L2142-L2178","documentation":"validateIPv6NAT46x64CIDR parses IPv6NAT46x64CIDR (the NAT46x64 translation prefix) and requires it to be exactly /96, per RFC 6052 which reserves /96 for embedding IPv4 addresses in IPv6. Any other prefix length is rejected.","triggerScenarios":"Calling DaemonConfig.Validate() (via validateIPv6NAT46x64CIDR) when --ipv6-nat46x64-cidr is a valid IPv6 prefix but its Bits() != 96 — e.g. /64 or /128.","commonSituations":"Reusing an existing /64 subnet as the NAT46x64 prefix; omitting configuration so a defaulted/wrong prefix is validated; hand-editing values in the cilium-config ConfigMap without knowing the RFC 6052 /96 requirement.","solutions":["Set --ipv6-nat46x64-cidr to a dedicated /96, e.g. 64:ff9b::/96 (RFC 6052 well-known prefix)","Choose any unused /96 inside your IPv6 ULA/GUA space and ensure it does not collide with pod/node prefixes","Update the cilium-config ConfigMap/Helm value ipv6 Nat46x64CIDR and restart the agent"],"exampleFix":"// before\nipv6-nat46x64-cidr: \"fd00:dead:beef::/64\"\n// after\nipv6-nat46x64-cidr: \"64:ff9b::/96\"","handlingStrategy":"validation","validationCode":"func checkNAT46x64CIDR(s string) error {\n    p, err := netip.ParsePrefix(s)\n    if err != nil {\n        return fmt.Errorf(\"invalid prefix %q: %w\", s, err)\n    }\n    if p.Bits() != 96 {\n        return fmt.Errorf(\"%q must be /96 (RFC 6052), got /%d\", s, p.Bits())\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := daemonConfig.Validate(vp); err != nil {\n    if strings.Contains(err.Error(), \"Prefix length must be /96\") {\n        log.Fatalf(\"ipv6-nat46x64-cidr must be /96 per RFC 6052: %v\", err)\n    }\n    return err\n}","preventionTips":["Use 64:ff9b::/96 (the RFC 6052 well-known prefix) unless you have a reason not to","Never reuse an existing /64 subnet as the NAT46x64 prefix","Remember: the option is validated only when NAT46x64 features are configured — set it explicitly","Check the rendered Helm value with helm template before applying"],"tags":["config","validation","ipv6","nat46","cidr"],"backgroundTag":"cidr-prefix-length-invalid","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}