{"record":{"id":"c29ae70e1ba84f48","repo":"hashicorp/terraform","slug":"ipv6-addresses-cannot-have-a-netmask-s","errorCode":null,"errorMessage":"IPv6 addresses cannot have a netmask: %s","messagePattern":"IPv6 addresses cannot have a netmask: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lang/funcs/cidr.go","lineNumber":70,"sourceCode":"// CidrNetmaskFunc contructs a function that converts an IPv4 address prefix given\n// in CIDR notation into a subnet mask address.\nvar CidrNetmaskFunc = function.New(&function.Spec{\n\tParams: []function.Parameter{\n\t\t{\n\t\t\tName: \"prefix\",\n\t\t\tType: cty.String,\n\t\t},\n\t},\n\tType:         function.StaticReturnType(cty.String),\n\tRefineResult: refineNotNull,\n\tImpl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {\n\t\t_, network, err := ipaddr.ParseCIDR(args[0].AsString())\n\t\tif err != nil {\n\t\t\treturn cty.UnknownVal(cty.String), fmt.Errorf(\"invalid CIDR expression: %s\", err)\n\t\t}\n\n\t\tif network.IP.To4() == nil {\n\t\t\treturn cty.UnknownVal(cty.String), fmt.Errorf(\"IPv6 addresses cannot have a netmask: %s\", args[0].AsString())\n\t\t}\n\n\t\treturn cty.StringVal(ipaddr.IP(network.Mask).String()), nil\n\t},\n})\n\n// CidrSubnetFunc contructs a function that calculates a subnet address within\n// a given IP network address prefix.\nvar CidrSubnetFunc = function.New(&function.Spec{\n\tParams: []function.Parameter{\n\t\t{\n\t\t\tName: \"prefix\",\n\t\t\tType: cty.String,\n\t\t},\n\t\t{\n\t\t\tName: \"newbits\",\n\t\t\tType: cty.Number,\n\t\t},","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/lang/funcs/cidr.go#L52-L88","documentation":"Returned by the cidrnetmask built-in (CidrNetmaskFunc, internal/lang/funcs/cidr.go:70) when the prefix parsed successfully (so it is not error 955) but network.IP.To4() == nil, i.e. the parsed CIDR is IPv6. cidrnetmask is defined only for IPv4 (dotted-decimal netmask has no meaning for IPv6, which uses prefix-length notation), so an IPv6 input is explicitly rejected even though it is a valid CIDR.","triggerScenarios":"Calling cidrnetmask(\"2001:db8::/32\") or any IPv6 CIDR; the prefix parses fine but To4() returns nil, triggering the IPv6-specific message. The original string is echoed back so the user sees exactly what they passed.","commonSituations":"Dual-stack configs where the CIDR variable may resolve to IPv6; copy-pasting an IPv6 prefix into an IPv4-only cidrnetmask call; attempting to compute a netmask for an IPv6 subnet (not supported).","solutions":["Use cidrnetmask only with IPv4 prefixes; for IPv6 use the prefix length directly (/N).","Branch on address family: compute netmask for v4 and use prefixlen for v6.","Validate the prefix is IPv4 (contains only dotted-decimal octets) before calling cidrnetmask.","Use the can() / try() functions to gracefully fall back for dual-stack variables."],"exampleFix":"# before (HCL)\nmask = cidrnetmask(var.cidr)  # var.cidr = \"2001:db8::/32\" -> IPv6 addresses cannot have a netmask\n\n# after\nlocals {\n  is_v6 = can(regex(\":\", var.cidr))\n  mask  = local.is_v6 ? null : cidrnetmask(var.cidr)\n}\n# or\nmask = can(cidrnetmask(var.cidr)) ? cidrnetmask(var.cidr) : null","handlingStrategy":"type-guard","validationCode":"# (HCL) branch on address family\nlocals {\n  is_v6 = can(regex(\":\", var.cidr))\n  mask  = local.is_v6 ? null : cidrnetmask(var.cidr)\n}","typeGuard":"// (Go) true if the CIDR is IPv4 (safe for cidrnetmask)\nfunc isIPv4CIDR(s string) bool {\n    _, n, err := net.ParseCIDR(s)\n    return err == nil && n.IP.To4() != nil\n}","tryCatchPattern":"# (HCL)\nvalue = can(cidrnetmask(var.cidr)) ? cidrnetmask(var.cidr) : null","preventionTips":["Use cidrnetmask only for IPv4 prefixes.","For IPv6 use the prefix length directly.","Detect family (presence of ':') before calling.","Use can()/try() for dual-stack CIDR variables."],"tags":["cidr","ipv6","netmask","hcl-function","validation"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}