{"record":{"id":"7b6059854614e491","repo":"gofr-dev/gofr","slug":"no-token-available","errorCode":null,"errorMessage":"no token available","messagePattern":"no token available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/service/file_token_auth.go","lineNumber":25,"sourceCode":"\t\"net/http\"\n\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","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/service/file_token_auth.go#L7-L43","documentation":"errTokenUnavailable is returned by FileTokenAuthConfig.currentToken (file_token_auth.go:25) when the in-memory cached token is an empty string at the moment a request needs a bearer header injected. Under normal construction this cannot happen (the constructor reads eagerly), so it guards the race where a refresh has wiped the token or the config was built without one.","triggerScenarios":"A fileTokenDecorator method (Get/Post/Put/Patch/Delete with headers) calls inject -> currentToken while the cached f.token is \"\" — e.g. after a refresh failure path that cleared the token, or misuse of a zero-value FileTokenAuthConfig not created via NewFileTokenAuthConfig.","commonSituations":"Constructing the decorator manually and skipping NewFileTokenAuthConfig; the token file being deleted and refresh failing repeatedly leaving an unusable state; shutting the service down while requests are still in flight.","solutions":["Always create the auth config via NewFileTokenAuthConfig so the token is loaded before use.","Check the file at tokenFilePath exists and is readable; refresh failures are logged at WARN by the refresh loop — fix the file so refresh repopulates the token.","Retry the request after the next refresh interval once the token file is restored.","Close the config and re-create it if the token source is permanently gone."],"exampleFix":"// before\ndec := &service.fileTokenDecorator{source: cfg} // cfg built by hand, token empty\n// after\ncfg, err := service.NewFileTokenAuthConfig(service.WithTokenFilePath(path)) // eager token load","handlingStrategy":"type-guard","validationCode":"cfg, err := service.NewFileTokenAuthConfig(opts...)\nif err != nil { return err } // ensures token loaded\nif cfg == nil { return errors.New(\"nil auth config\") }","typeGuard":"func tokenReady(cfg *service.FileTokenAuthConfig) bool {\n\treturn cfg != nil // construction guarantees a non-empty cached token\n}","tryCatchPattern":"headers, err := decorator.inject(headers)\nif errors.Is(err, service.ErrTokenUnavailable) {\n\t// retry after refresh interval or recreate config\n}","preventionTips":["Always build the config through NewFileTokenAuthConfig, never by struct literal.","Fail fast on constructor errors instead of continuing with a partial config.","Keep the token file present so the refresh loop never degrades to an unusable state.","Gracefully stop in-flight requests before calling Close."],"tags":["auth","bearer-token","kubernetes"],"backgroundTag":"no-credentials-available","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}