{"record":{"id":"21e0c6684d159056","repo":"slackhq/nebula","slug":"config-s-interfaces-is-invalid-type-t-v","errorCode":null,"errorMessage":"config `%s.interfaces` is invalid (type %T): %v","messagePattern":"config `(.+?)\\.interfaces` is invalid \\(type %T\\): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"allow_list.go","lineNumber":176,"sourceCode":"\t}\n\n\tif !rules6.defaultSet {\n\t\tif rules6.allValuesMatch {\n\t\t\ttree.Insert(netip.PrefixFrom(netip.IPv6Unspecified(), 0), !rules6.allValues)\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"config `%s` contains both true and false rules, but no default set for ::/0\", k)\n\t\t}\n\t}\n\n\treturn &AllowList{cidrTree: tree}, nil\n}\n\nfunc getAllowListInterfaces(k string, v any) ([]AllowListNameRule, error) {\n\tvar nameRules []AllowListNameRule\n\n\trawRules, ok := v.(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"config `%s.interfaces` is invalid (type %T): %v\", k, v, v)\n\t}\n\n\tfirstEntry := true\n\tvar allValues bool\n\tfor name, rawAllow := range rawRules {\n\t\tallow, ok := config.AsBool(rawAllow)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"config `%s.interfaces` has invalid value (type %T): %v\", k, rawAllow, rawAllow)\n\t\t}\n\n\t\tnameRE, err := regexp.Compile(\"^\" + name + \"$\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"config `%s.interfaces` has invalid key: %s: %v\", k, name, err)\n\t\t}\n\n\t\tnameRules = append(nameRules, AllowListNameRule{\n\t\t\tName:  nameRE,\n\t\t\tAllow: allow,","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/allow_list.go#L158-L194","documentation":"getAllowListInterfaces parses the `interfaces` sub-block of an allow list, which must be a map of interface name patterns to booleans. If the value is not a map[string]any (e.g. a string, list, or bool), the config is rejected with the offending type shown in %T.","triggerScenarios":"NewRemoteAllowListFromConfig / newAllowListFromConfig where the `interfaces` key holds a scalar or array instead of a mapping of names to true/false.","commonSituations":"Copy-paste mistakes nesting `interfaces` at the wrong level, or using YAML list syntax (- eth0) instead of a map.","solutions":["Make `interfaces` a mapping like { eth0: true, \"wg-.*\": false }","Remove surrounding quotes or list syntax around the interfaces block"],"exampleFix":"// before\nallow_list:\n  interfaces:\n    - eth0\n// after\nallow_list:\n  interfaces:\n    eth0: true","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isInterfacesMap(v any) bool {\n\tm, ok := v.(map[string]any)\n\tif !ok {\n\t\treturn false\n\t}\n\tfor _, val := range m {\n\t\tif _, ok := val.(bool); !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":null,"preventionTips":["Keep `interfaces` as a map of name pattern -> bool","Avoid YAML list syntax for interfaces"],"tags":["config","validation","interfaces","allowlist"],"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"}