{"record":{"id":"362ddf03b1b7794b","repo":"gofiber/fiber","slug":"fiber-keyauth-scope-requires-insufficient-scope-e","errorCode":null,"errorMessage":"fiber: keyauth scope requires insufficient_scope error","messagePattern":"fiber: keyauth scope requires insufficient_scope error","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/keyauth/config.go","lineNumber":160,"sourceCode":"\tif cfg.ErrorURI != \"\" {\n\t\tif cfg.Error == \"\" {\n\t\t\tpanic(\"fiber: keyauth error_uri requires error\")\n\t\t}\n\t\tif u, err := url.Parse(cfg.ErrorURI); err != nil || !u.IsAbs() {\n\t\t\tpanic(\"fiber: keyauth error_uri must be absolute\")\n\t\t}\n\t}\n\tif cfg.Error == ErrorInsufficientScope {\n\t\tif cfg.Scope == \"\" {\n\t\t\tpanic(\"fiber: keyauth insufficient_scope requires scope\")\n\t\t}\n\t\tfor scope := range strings.SplitSeq(cfg.Scope, \" \") {\n\t\t\tif scope == \"\" || !isScopeToken(scope) {\n\t\t\t\tpanic(\"fiber: keyauth scope contains invalid token\")\n\t\t\t}\n\t\t}\n\t} else if cfg.Scope != \"\" {\n\t\tpanic(\"fiber: keyauth scope requires insufficient_scope error\")\n\t}\n\n\treturn cfg\n}\n\nfunc isScopeToken(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tc := s[i]\n\t\tif c < 0x21 || c > 0x7e || c == '\"' || c == '\\\\' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn s != \"\"\n}\n","sourceCodeStart":142,"sourceCodeEnd":175,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/keyauth/config.go#L142-L175","documentation":"The mirror of error 292: Config.Scope may only be set when Config.Error == ErrorInsufficientScope. Setting Scope with any other (or empty) Error panics, because the scope parameter is only defined for insufficient_scope challenges in RFC 6750. This catches the inverse misconfiguration.","triggerScenarios":"keyauth.Config{Scope: \"read\"} with Error unset, or Error: keyauth.ErrorInvalidToken together with Scope: \"read\". The else-if at config.go:159 fires whenever Error is not insufficient_scope but Scope is non-empty.","commonSituations":"Configuring Scope globally because it looks useful, while Error is set per route to invalid_token; leftover Scope field from a previous insufficient_scope setup after Error was changed.","solutions":["Set Config.Error to keyauth.ErrorInsufficientScope if you want to advertise required scopes.","Remove Config.Scope if your Error is something else (or empty).","Validate at config load: Scope != \"\" implies Error == ErrorInsufficientScope."],"exampleFix":"// before\napp.Use(keyauth.New(keyauth.Config{\n    Validator: v,\n    Error:     keyauth.ErrorInvalidToken,\n    Scope:     \"read\",\n}))\n\n// after — scope belongs only to insufficient_scope\napp.Use(keyauth.New(keyauth.Config{\n    Validator: v,\n    Error:     keyauth.ErrorInsufficientScope,\n    Scope:     \"read\",\n}))","handlingStrategy":"validation","validationCode":"if cfg.Scope != \"\" && cfg.Error != keyauth.ErrorInsufficientScope {\n    log.Fatal(\"keyauth: Scope is only valid with Error=insufficient_scope\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair Scope exclusively with the insufficient_scope error code.","When changing Error, clear Scope unless the new value is insufficient_scope.","Add a config validator asserting (Scope != \"\") ⟹ (Error == insufficient_scope)."],"tags":["keyauth","oauth","scope","rfc-6750","config","auth","startup-panic"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}