grpc/grpc-go · error
tokenFilePath cannot be empty
Error message
tokenFilePath cannot be empty
What it means
Thrown by jwt.NewTokenFileCallCredentials when the supplied tokenFilePath argument is the empty string (token_file_call_creds.go:57). The JWT-from-file call-credentials implementation (gRFC A97) needs a concrete filesystem path to read and refresh Bearer tokens from, so an empty path cannot produce a usable credential. It is a construction-time programmer error, not a runtime transport failure.
Source
Thrown at credentials/jwt/token_file_call_creds.go:57
type jwtTokenFileCallCreds struct {
fileReader *jwtFileReader
backoffStrategy backoff.Strategy
// cached data protected by mu
mu sync.Mutex
cachedAuthHeader string // "Bearer " + token
cachedExpiry time.Time // Slightly less than actual expiration time
cachedError error // Error from last failed attempt
retryAttempt int // Current retry attempt number
nextRetryTime time.Time // When next retry is allowed
pendingRefresh bool // Whether a refresh is currently in progress
}
// NewTokenFileCallCredentials creates PerRPCCredentials that reads JWT tokens
// from the specified file path.
func NewTokenFileCallCredentials(tokenFilePath string) (credentials.PerRPCCredentials, error) {
if tokenFilePath == "" {
return nil, fmt.Errorf("tokenFilePath cannot be empty")
}
creds := &jwtTokenFileCallCreds{
fileReader: &jwtFileReader{tokenFilePath: tokenFilePath},
backoffStrategy: backoff.DefaultExponential,
}
return creds, nil
}
// GetRequestMetadata gets the current request metadata, refreshing tokens if
// required. This implementation follows the PerRPCCredentials interface. The
// tokens will get automatically refreshed if they are about to expire or if
// they haven't been loaded successfully yet.
// If it's not possible to extract a token from the file, UNAVAILABLE is
// returned.
// If the token is extracted but invalid, then UNAUTHENTICATED is returned.
// If errors are encoutered, a backoff is applied before retrying.View on GitHub (pinned to 03255a9237)
Solutions
- Pass a non-empty, absolute path to a readable file when calling NewTokenFileCallCredentials.
- Validate the config source (env var / flag) for emptiness and fail fast at startup with a clear message.
- If the path comes from a secret mount, confirm the volume/secret is mounted and the path key is correct.
Example fix
// before
creds, err := jwt.NewTokenFileCallCredentials(os.Getenv("JWT_TOKEN_FILE"))
// after
path := os.Getenv("JWT_TOKEN_FILE")
if path == "" {
log.Fatal("JWT_TOKEN_FILE must be set")
}
creds, err := jwt.NewTokenFileCallCredentials(path) Defensive patterns
Strategy: validation
Validate before calling
path := os.Getenv("JWT_TOKEN_FILE")
if strings.TrimSpace(path) == "" {
log.Fatal("JWT_TOKEN_FILE must be a non-empty file path")
}
if _, err := os.Stat(path); err != nil {
log.Fatalf("token file not accessible: %v", err)
}
creds, err := jwt.NewTokenFileCallCredentials(path)
if err != nil { log.Fatal(err) } Type guard
// PerRPCCredentials must be non-nil and transport-secure; guard at construction:
func mustJWTCallCreds(path string) credentials.PerRPCCredentials {
if path == "" { panic("empty tokenFilePath") }
c, err := jwt.NewTokenFileCallCredentials(path)
if err != nil { panic(err) }
return c
} Prevention
- Resolve all credential file paths from config at startup and fail fast on empty/missing values.
- Use absolute paths for token files and verify readability before dialing.
- Unit-test credential construction with the real config object to catch empty-string fields.
When it happens
Trigger: Calling jwt.NewTokenFileCallCredentials("") directly, or passing an unset/zero-value string variable (e.g. an env var like os.Getenv("JWT_TOKEN_FILE") that was never exported, or a struct field left as its default) into the constructor.
Common situations: Deployment env where the JWT token-file path is injected via an env var or secret mount that is missing/misspelled; tests that forget to set the path; config loaders that swallow the missing-key case and return "" instead of failing.
Related errors
- credentials: audience cannot be empty
- token file %q: %v: %w
- no expiration claims
- cannot send secure credentials on an insecure connection: %v
- credentials: failed to read the service account key file: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/b6d34b794819c032.
Report an issue: GitHub.