{"record":{"id":"13259976e1c94c67","repo":"slackhq/nebula","slug":"config-s-interfaces-values-must-all-be-the-same","errorCode":null,"errorMessage":"config `%s.interfaces` values must all be the same true/false value","messagePattern":"config `(.+?)\\.interfaces` values must all be the same true/false value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"allow_list.go","lineNumber":202,"sourceCode":"\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,\n\t\t})\n\n\t\tif firstEntry {\n\t\t\tallValues = allow\n\t\t\tfirstEntry = false\n\t\t} else {\n\t\t\tif allow != allValues {\n\t\t\t\treturn nil, fmt.Errorf(\"config `%s.interfaces` values must all be the same true/false value\", k)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nameRules, nil\n}\n\nfunc getRemoteAllowRanges(c *config.C, k string) (*bart.Table[*AllowList], error) {\n\tvalue := c.Get(k)\n\tif value == nil {\n\t\treturn nil, nil\n\t}\n\n\tremoteAllowRanges := new(bart.Table[*AllowList])\n\n\trawMap, ok := value.(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"config `%s` has invalid type: %T\", k, value)","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/allow_list.go#L184-L220","documentation":"All values in an `interfaces` block must agree: either every interface is allowed (true) or every one is denied (false). Mixing true and false without a way to express a default is rejected, since name rules alone cannot resolve a fallback decision.","triggerScenarios":"getAllowListInterfaces where entries include both eth0: true and eth1: false in the same interfaces map.","commonSituations":"Admins trying to express allowlist AND blocklist semantics in one interfaces block; the schema only supports a single-direction list.","solutions":["Make all interface values the same boolean","If you need both allow and deny semantics, split into multiple allow lists or use CIDR rules with an explicit 0.0.0.0/0 / ::/0 default"],"exampleFix":"// before\ninterfaces:\n  eth0: true\n  eth1: false\n// after\ninterfaces:\n  eth0: true\n  eth1: true","handlingStrategy":"validation","validationCode":"func interfaceValuesConsistent(m map[string]any) bool {\n\tvar first bool\n\ti := 0\n\tfor _, v := range m {\n\t\tb, ok := v.(bool)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tif i == 0 {\n\t\t\tfirst = b\n\t\t} else if b != first {\n\t\t\treturn false\n\t\t}\n\t\ti++\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a single boolean value across all interface entries","Express opposite semantics in a separate allow list"],"tags":["config","validation","interfaces","allowlist"],"backgroundTag":"inconsistent-config-values","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"}