jaegertracing/jaeger · error
failed to get token from file: %w
Error message
failed to get token from file: %w
What it means
TokenProviderWithTime in internal/auth/tokenloader.go:63 wraps errors from the initial token load with this message. It creates a cached file token loader and immediately calls it once; if that first read of the token file fails, the provider cannot be constructed and the error (which internally wraps "failed to read token file") is returned. Callers include TokenProvider (production) and the auth setup path initTokenAuthWithTime.
Source
Thrown at internal/auth/tokenloader.go:63
cachedToken = strings.TrimRight(string(b), "\r\n")
lastRead = now
return cachedToken, nil
}
}
// TokenProvider creates a token provider that handles file loading and error handling consistently.
func TokenProvider(path string, interval time.Duration, logger *zap.Logger) (func() string, error) {
return TokenProviderWithTime(path, interval, logger, time.Now) // Use real time.Now in production
}
// TokenProviderWithTime creates a token provider with injectable time (for testing)
func TokenProviderWithTime(path string, interval time.Duration, logger *zap.Logger, timeFn func() time.Time) (func() string, error) {
loader := cachedFileTokenLoader(path, interval, timeFn)
// current token load
currentToken, err := loader()
if err != nil {
return nil, fmt.Errorf("failed to get token from file: %w", err)
}
// currentToken is the last successfully loaded token, held so it can be
// returned as a fallback if a later reload fails. The returned closure is
// invoked by the auth RoundTripper on every HTTP request and may run
// concurrently, so access is guarded by mu. A mutex (rather than an
// atomic.Pointer/atomic.Value) keeps this hot path allocation-free.
var mu sync.Mutex
return func() string {
newToken, err := loader()
mu.Lock()
defer mu.Unlock()
if err != nil {
logger.Warn("Token reload failed", zap.Error(err))
return currentToken
}View on GitHub (pinned to 806f444784)
Solutions
- Ensure the token file exists and is readable before starting the service; fix the configured path if wrong
- For Kubernetes, confirm the secret is mounted and populated (kubectl describe pod; check the mount path) and add an init container if ordering matters
- Re-run with the file in place — the error occurs only at provider construction, so once the file is readable, TokenProvider succeeds
- Inspect the wrapped inner error (failed to read token file: <os error>) to distinguish ENOENT vs EACCES and fix accordingly
Example fix
// before
// provider, err := auth.TokenProvider("/wrong/path/token", time.Minute, logger)
// after
// const tokenPath = "/var/run/secrets/token" // path that actually exists
// provider, err := auth.TokenProvider(tokenPath, time.Minute, logger)
// if err != nil { logger.Fatal("auth init failed", zap.Error(err)) } Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast at startup with a clear message if the token file is missing
if _, err := os.Stat(tokenPath); err != nil {
return nil, fmt.Errorf("token file %s not found (check secret mount): %w", tokenPath, err)
} Try / catch
tokenFn, err := auth.TokenProviderWithTime(path, interval, logger, time.Now)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {
logger.Sugar().Fatalf("token file %q missing; fix the path or secret mount", path)
}
return fmt.Errorf("init token auth: %w", err)
} Prevention
- Validate the token path at config-parse time, before service wiring
- In Kubernetes, add an initContainer or readiness gate that waits for the secret file to appear
- Distinguish ENOENT vs EACCES by inspecting the wrapped fs.PathError to fix path vs permission issues
- Keep a deployment test that starts the service with a real mounted secret to catch path drift
When it happens
Trigger: Calling auth.TokenProvider(path, interval, logger) or TokenProviderWithTime(path, interval, logger, timeFn) where the initial loader() call fails because the token file at path is missing, unreadable, or is a directory.
Common situations: Service startup in Kubernetes before the projected secret/token volume is populated; misconfigured token file path in the HTTP auth settings; running the binary locally without creating the token file; permissions changed on the secret file.
Related errors
- failed to read token file: %w
- server with TLS enabled can not use same host ports for gRPC
- unknown metrics backend specified
- error creating Elasticsearch client: %w
- failed to create Elasticsearch client: %w
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/7b7c2f50743076f1.
Report an issue: GitHub.