{"id":"3dd0367705034193","repo":"gofiber/fiber","slug":"fiber-keyauth-error-uri-must-be-absolute","errorCode":null,"errorMessage":"fiber: keyauth error_uri must be absolute","messagePattern":"fiber: keyauth error_uri must be absolute","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/keyauth/config.go","lineNumber":147,"sourceCode":"\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\n\treturn cfg\n}\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/keyauth/config.go#L129-L165","documentation":"When keyauth Config.ErrorURI is provided, the library parses it with url.Parse and requires an absolute URL (one with a scheme and host, e.g. https://...). A relative path or a value that fails to parse panics in configDefault(), because RFC 6750 requires error_uri to be an absolute URI.","triggerScenarios":"Setting Config.ErrorURI to a relative path like \"/docs/errors\", a path without scheme like \"example.com/errors\", or a malformed string that url.Parse rejects. This triggers the panic at middleware construction.","commonSituations":"Developer reuses an internal route path instead of a fully-qualified URL. Environment-specific base URLs omitted because the dev assumed a relative path is fine. Copying a path from a frontend router config.","solutions":["Provide a full absolute URL including scheme, e.g. \"https://example.com/docs/auth-errors\".","Build the URL from a configured base so it stays absolute across environments.","Verify the value parses with net/url and u.IsAbs() returns true before passing it to keyauth.New()."],"exampleFix":"// before\napp.Use(keyauth.New(keyauth.Config{\n    Validator: validateKey,\n    Error:     keyauth.ErrorInvalidToken,\n    ErrorURI:  \"/docs/auth-errors\",\n}))\n// after\napp.Use(keyauth.New(keyauth.Config{\n    Validator: validateKey,\n    Error:     keyauth.ErrorInvalidToken,\n    ErrorURI:  \"https://example.com/docs/auth-errors\",\n}))","handlingStrategy":"validation","validationCode":"if cfg.ErrorURI != \"\" {\n    u, err := url.Parse(cfg.ErrorURI)\n    if err != nil || !u.IsAbs() {\n        log.Fatalf(\"keyauth: ErrorURI %q must be an absolute URL\", cfg.ErrorURI)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store fully-qualified base URLs in config and concatenate paths onto them.","Run url.Parse + IsAbs() in a config-validation step before constructing middleware."],"tags":["keyauth","config","auth","rfc6750","url","panic"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}