{"record":{"id":"91ddd18be6e32ac2","repo":"gofr-dev/gofr","slug":"authorization-header-already-set-on-request","errorCode":null,"errorMessage":"authorization header already set on request","messagePattern":"authorization header already set on request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/service/file_token_auth.go","lineNumber":26,"sourceCode":"\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"gofr.dev/pkg/gofr/logging\"\n)\n\nconst (\n\t// DefaultTokenFilePath is the standard Kubernetes projected service account token mount path.\n\tDefaultTokenFilePath = \"/var/run/secrets/kubernetes.io/serviceaccount/token\" // #nosec G101 -- file path, not a credential\n\n\tdefaultRefreshInterval = 30 * time.Second\n)\n\nvar (\n\terrEmptyTokenFile    = errors.New(\"token file is empty\")\n\terrTokenUnavailable  = errors.New(\"no token available\")\n\terrAuthHeaderPresent = errors.New(\"authorization header already set on request\")\n)\n\n// FileTokenAuthConfig reads a bearer token from a local file and periodically\n// re-reads it to support token rotation (e.g. Kubernetes projected service\n// account tokens).\n//\n// The returned value implements Options, Observable and\n// io.Closer. Call Close to stop the background refresh goroutine; it is safe\n// to call Close multiple times.\ntype FileTokenAuthConfig struct {\n\ttokenFilePath   string\n\trefreshInterval time.Duration\n\n\tlogger logging.Logger\n\n\tmu    sync.RWMutex\n\ttoken string\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/service/file_token_auth.go#L8-L44","documentation":"errAuthHeaderPresent is returned by fileTokenDecorator.inject (file_token_auth.go:26) when the outgoing request already carries a non-empty Authorization header. FileTokenAuthConfig is an automatic bearer-token injector; it refuses to silently overwrite a caller-supplied credential, wrapping the sentinel in AuthErr so the caller knows their explicit header collided with injection.","triggerScenarios":"Calling any GetWithHeaders/PostWithHeaders/PutWithHeaders/PatchWithHeaders/DeleteWithHeaders on a service decorated with FileTokenAuthConfig while passing headers containing Authorization with a non-empty value (also exercised directly by TestFileTokenAuthConfig_RejectsExistingAuthHeader).","commonSituations":"Adding your own \"Authorization: Bearer <my-token>\" in headers while also enabling file-token auth on the service; middleware that sets auth headers upstream of the decorator; migrating code that previously did manual auth into a decorated service.","solutions":["Remove the Authorization header from your explicit headers map and let FileTokenAuthConfig inject the file-based token.","If you need a custom credential, do not add FileTokenAuthConfig (AddOption) to that HTTP service.","If you intended both, chain two services instead of mixing header auth with file-token auth on one request.","Check for empty-string-only headers: the guard only fires when the existing value is non-empty, so clearing the header fixes it."],"exampleFix":"// before\nsvc.GetWithHeaders(ctx, \"/x\", nil, map[string]string{\"Authorization\": \"Bearer manual\"})\n// after\nsvc.GetWithHeaders(ctx, \"/x\", nil, nil) // token injected from file","handlingStrategy":"validation","validationCode":"if h, ok := headers[\"Authorization\"]; ok && h != \"\" {\n\tdelete(headers, \"Authorization\") // let file-token auth inject\n}","typeGuard":"func hasAuthHeader(headers map[string]string) bool {\n\tv, ok := headers[\"Authorization\"]\n\treturn ok && v != \"\"\n}","tryCatchPattern":"resp, err := svc.GetWithHeaders(ctx, path, qp, headers)\nvar ae service.AuthErr\nif errors.As(err, &ae) && errors.Is(ae.Err, errAuthHeaderPresent) {\n\t// drop the manual Authorization header and retry once\n}","preventionTips":["Pick one auth mechanism per service: file-token injection OR manual headers, never both.","Audit middleware/interceptors for code that sets Authorization on outgoing requests.","When migrating to decorated services, remove legacy header-setting code.","Document in team conventions that explicit Authorization headers are rejected on decorated services."],"tags":["auth","http-headers","conflict"],"backgroundTag":"authorization-header-conflict","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}