{"record":{"id":"0b094c580f338294","repo":"slackhq/nebula","slug":"invalid-mask-s","errorCode":null,"errorMessage":"invalid mask: %s","messagePattern":"invalid mask: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"calculated_remote.go","lineNumber":142,"sourceCode":"}\n\nfunc newCalculatedRemotesEntryFromConfig(cidr netip.Prefix, raw any) (*calculatedRemote, error) {\n\trawMap, ok := raw.(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid type: %T\", raw)\n\t}\n\n\trawValue := rawMap[\"mask\"]\n\tif rawValue == nil {\n\t\treturn nil, fmt.Errorf(\"missing mask: %v\", rawMap)\n\t}\n\trawMask, ok := rawValue.(string)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid mask (type %T): %v\", rawValue, rawValue)\n\t}\n\tmaskCidr, err := netip.ParsePrefix(rawMask)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid mask: %s\", rawMask)\n\t}\n\n\tvar port int\n\trawValue = rawMap[\"port\"]\n\tif rawValue == nil {\n\t\treturn nil, fmt.Errorf(\"missing port: %v\", rawMap)\n\t}\n\tswitch v := rawValue.(type) {\n\tcase int:\n\t\tport = v\n\tcase string:\n\t\tport, err = strconv.Atoi(v)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid port: %s: %w\", v, err)\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid port (type %T): %v\", rawValue, rawValue)\n\t}","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/calculated_remote.go#L124-L160","documentation":"This error is returned by newCalculatedRemotesEntryFromConfig when the 'mask' value in a calculated_remotes config entry cannot be parsed as an IP prefix. Nebula requires the mask to be a valid CIDR prefix (e.g. 10.0.0.0/8) so it can compute calculated remote hosts by masking target IPs. Parse failures of the string with netip.ParsePrefix produce this message carrying the raw offending value.","triggerScenarios":"Calling newCalculatedRemotesListFromConfig with a config map whose calculated_remotes entry has a 'mask' key set to a string that is not a valid CIDR prefix, e.g. mask: 255.255.0.0 or mask: 10.0.0.0/33 or mask: not-a-mask.","commonSituations":"Users copying subnet masks from netmask notation (255.255.255.0) instead of CIDR (/24), typos in the prefix length, or omitting the /prefix part entirely when writing the Nebula YAML config.","solutions":["Change the mask value to a valid CIDR prefix, e.g. mask: 10.0.0.0/8 instead of a dotted netmask","Verify the prefix length is in range (0-32 for IPv4, 0-128 for IPv6)","Check the config value is not quoted or padded with stray whitespace/characters","Validate locally with `netip.ParsePrefix` or an online CIDR checker before deploying"],"exampleFix":"// before\ncalculated_remotes:\n  - mask: 255.255.0.0\n    port: 4242\n// after\ncalculated_remotes:\n  - mask: 10.0.0.0/16\n    port: 4242","handlingStrategy":"validation","validationCode":"func validMask(v string) bool {\n    _, err := netip.ParsePrefix(strings.TrimSpace(v))\n    return err == nil\n}\n// before launching nebula: ensure every calculated_remotes mask passes validMask","typeGuard":"func asMaskString(raw any) (string, bool) {\n    s, ok := raw.(string)\n    if !ok || !validMask(s) {\n        return \"\", false\n    }\n    return s, true\n}","tryCatchPattern":"if err != nil {\n    var cfgErr *ConfigError\n    if errors.As(err, &cfgErr) {\n        log.Fatalf(\"calculated_remotes mask invalid: %v\", err)\n    }\n    return err\n}","preventionTips":["Always write masks in CIDR notation (10.0.0.0/8), never dotted netmask form","Lint the Nebula YAML with a schema validator before deploying","Test config parsing with nebula -config ... -test in CI","Keep mask values unquoted plain strings to avoid stray whitespace"],"tags":["config","yaml","cidr","network"],"backgroundTag":"invalid-config-value","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}