{"record":{"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/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/keyauth/config.go#L122-L158","documentation":"RFC 6750 requires error_description to appear only alongside an error parameter in a WWW-Authenticate challenge. keyauth enforces this: setting Config.ErrorDescription while Config.Error is empty panics. The descriptionqualifies the error; without an error code it has no meaning to the client.","triggerScenarios":"keyauth.Config{ErrorDescription: \"token expired\"} with no Error set. Also reached when Error is populated conditionally but ErrorDescription is set unconditionally.","commonSituations":"Wanting a human-readable challenge message but forgetting the mandatory machine-readable error code; refactoring that removes the Error assignment but leaves ErrorDescription; building the challenge fields from separate config keys that got out of sync.","solutions":["Also set Config.Error to one of the three allowed codes (e.g. keyauth.ErrorInvalidToken).","Remove ErrorDescription if you do not need a human-readable hint.","Validate at config load: if ErrorDescription != \"\" then Error must be non-empty."],"exampleFix":"// before\napp.Use(keyauth.New(keyauth.Config{\n    Validator:        v,\n    ErrorDescription: \"the token has expired\",\n}))\n\n// after\napp.Use(keyauth.New(keyauth.Config{\n    Validator:        v,\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\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set Error when adding ErrorDescription.","Keep the RFC 6750 challenge fields (Error, ErrorDescription, ErrorURI) configured together.","Validate the Error→description dependency at config load."],"tags":["keyauth","oauth","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"}