gofr-dev/gofr · error
no token available
Error message
no token available
What it means
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.
Source
Thrown at pkg/gofr/service/file_token_auth.go:25
"net/http"
"os"
"strings"
"sync"
"time"
"gofr.dev/pkg/gofr/logging"
)
const (
// DefaultTokenFilePath is the standard Kubernetes projected service account token mount path.
DefaultTokenFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/token" // #nosec G101 -- file path, not a credential
defaultRefreshInterval = 30 * time.Second
)
var (
errEmptyTokenFile = errors.New("token file is empty")
errTokenUnavailable = errors.New("no token available")
errAuthHeaderPresent = errors.New("authorization header already set on request")
)
// FileTokenAuthConfig reads a bearer token from a local file and periodically
// re-reads it to support token rotation (e.g. Kubernetes projected service
// account tokens).
//
// The returned value implements Options, Observable and
// io.Closer. Call Close to stop the background refresh goroutine; it is safe
// to call Close multiple times.
type FileTokenAuthConfig struct {
tokenFilePath string
refreshInterval time.Duration
logger logging.Logger
mu sync.RWMutex
token stringView on GitHub (pinned to 187eb24962)
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.
Example fix
// before
dec := &service.fileTokenDecorator{source: cfg} // cfg built by hand, token empty
// after
cfg, err := service.NewFileTokenAuthConfig(service.WithTokenFilePath(path)) // eager token load Defensive patterns
Strategy: type-guard
Validate before calling
cfg, err := service.NewFileTokenAuthConfig(opts...)
if err != nil { return err } // ensures token loaded
if cfg == nil { return errors.New("nil auth config") } Type guard
func tokenReady(cfg *service.FileTokenAuthConfig) bool {
return cfg != nil // construction guarantees a non-empty cached token
} Try / catch
headers, err := decorator.inject(headers)
if errors.Is(err, service.ErrTokenUnavailable) {
// retry after refresh interval or recreate config
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- token file is empty
- failed to read token from %s: %w
- api keys list is empty
- container is nil
- validate func is empty
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/7b6059854614e491.
Report an issue: GitHub.