{"id":"b52ad8f0eaa85308","repo":"gofiber/fiber","slug":"fiber-keyauth-error-description-requires-error","errorCode":null,"errorMessage":"fiber: keyauth error_description requires error","messagePattern":"fiber: keyauth error_description requires error","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/keyauth/config.go","lineNumber":140,"sourceCode":"\t\tcfg.SuccessHandler = ConfigDefault.SuccessHandler\n\t}\n\tif cfg.ErrorHandler == nil {\n\t\tcfg.ErrorHandler = ConfigDefault.ErrorHandler\n\t}\n\n\tif len(getAuthSchemes(cfg.Extractor)) == 0 && cfg.Challenge == \"\" {\n\t\tcfg.Challenge = fmt.Sprintf(\"ApiKey realm=%q\", cfg.Realm)\n\t}\n\n\tif cfg.Error != \"\" {\n\t\tswitch cfg.Error {\n\t\tcase ErrorInvalidRequest, ErrorInvalidToken, ErrorInsufficientScope:\n\t\tdefault:\n\t\t\tpanic(\"fiber: keyauth unsupported error token\")\n\t\t}\n\t}\n\tif cfg.ErrorDescription != \"\" && cfg.Error == \"\" {\n\t\tpanic(\"fiber: keyauth error_description requires error\")\n\t}\n\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}","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/keyauth/config.go#L122-L158","documentation":"The keyauth Config.ErrorDescription field is a sub-parameter of the RFC 6750 WWW-Authenticate challenge and is only meaningful when paired with an Error code. Setting ErrorDescription while leaving Error empty is an inconsistent state that the library rejects at construction via a panic in configDefault().","triggerScenarios":"Calling keyauth.New() with Config.ErrorDescription set to a non-empty string but Config.Error left at its zero value (\"\"). This commonly happens when a developer fills in the human-readable description but forgets the machine-readable error code.","commonSituations":"Porting a hand-built 401 response into keyauth config and only carrying over the descriptive text. Editing config incrementally and committing the description before the error code. Misreading docs that show ErrorDescription as standalone.","solutions":["Set Config.Error to a valid RFC 6750 code (invalid_request, invalid_token, or insufficient_scope) whenever you set ErrorDescription.","Remove the ErrorDescription value if you do not need the structured challenge parameters.","Validate the (Error, ErrorDescription) pairing in a helper before constructing the middleware."],"exampleFix":"// before\napp.Use(keyauth.New(keyauth.Config{\n    Validator:        validateKey,\n    ErrorDescription: \"the token has expired\",\n}))\n// after\napp.Use(keyauth.New(keyauth.Config{\n    Validator:        validateKey,\n    Error:            keyauth.ErrorInvalidToken,\n    ErrorDescription: \"the token has expired\",\n}))","handlingStrategy":"validation","validationCode":"if cfg.ErrorDescription != \"\" && cfg.Error == \"\" {\n    log.Fatal(\"keyauth: ErrorDescription requires Error to be set\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat Error as the required key that unlocks ErrorDescription and ErrorURI.","Build keyauth config via a helper that enforces the (Error, ErrorDescription) pairing."],"tags":["keyauth","config","auth","rfc6750","panic"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}