{"record":{"id":"aefc9be827b6ae83","repo":"gofiber/fiber","slug":"fiber-keyauth-error-uri-requires-error","errorCode":null,"errorMessage":"fiber: keyauth error_uri requires error","messagePattern":"fiber: keyauth error_uri requires error","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/keyauth/config.go","lineNumber":144,"sourceCode":"\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}\n\t} else if cfg.Scope != \"\" {\n\t\tpanic(\"fiber: keyauth scope requires insufficient_scope error\")\n\t}\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/keyauth/config.go#L126-L162","documentation":"Like error_description, RFC 6750's error_uri parameter is meaningful only when paired with an error code. keyauth panics when Config.ErrorURI is set but Config.Error is empty. error_uri is meant to give a link explaining the error, so it cannot stand alone in a challenge.","triggerScenarios":"keyauth.Config{ErrorURI: \"https://example.com/errors\"} with Error unset. Reached when ErrorURI is configured globally but Error is wired per-endpoint and missing on this instance.","commonSituations":"Setting a documentation link as ErrorURI by default but forgetting to set the Error code that triggers it; splitting error fields across config files that desync.","solutions":["Set Config.Error to a valid code (e.g. keyauth.ErrorInvalidToken) whenever ErrorURI is set.","Drop ErrorURI if no Error is configured.","Enforce the dependency in your config loader: ErrorURI requires Error."],"exampleFix":"// before\napp.Use(keyauth.New(keyauth.Config{\n    Validator: v,\n    ErrorURI:  \"https://docs.example.com/auth\",\n}))\n\n// after\napp.Use(keyauth.New(keyauth.Config{\n    Validator: v,\n    Error:     keyauth.ErrorInvalidToken,\n    ErrorURI:  \"https://docs.example.com/auth\",\n}))","handlingStrategy":"validation","validationCode":"if cfg.ErrorURI != \"\" && cfg.Error == \"\" {\n    log.Fatal(\"keyauth: ErrorURI requires Error\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat ErrorURI as subordinate to Error — set both or neither.","Keep challenge-related fields in one config block so they stay in sync.","Add a config validator that checks the Error prerequisite for ErrorURI."],"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"}