grpc/grpc-go · error
tokenFilePath cannot be empty
Error message
tokenFilePath cannot be empty
What it means
Returned by NewTokenFileCallCredentials when tokenFilePath is the empty string. This is a pure programming error: the constructor refuses to create a credential that could never read a token. No I/O is attempted.
Solutions
- Pass a non-empty absolute path to NewTokenFileCallCredentials.
- Validate the configured path at startup and fail fast with a clear message if empty.
- Set the missing environment variable (e.g. TOKEN_FILE) in the container/pod spec.
Example fix
// before
creds, err := jwt.NewTokenFileCallCredentials(os.Getenv("TOKEN_FILE"))
// after
path := os.Getenv("TOKEN_FILE")
if path == "" {
log.Fatal("TOKEN_FILE env var is required")
}
creds, err := jwt.NewTokenFileCallCredentials(path) Defensive patterns
Strategy: validation
Validate before calling
if tokenFilePath == "" {
log.Fatal("tokenFilePath is required")
}
creds, err := jwt.NewTokenFileCallCredentials(tokenFilePath) Type guard
func nonEmptyPath(p string) bool { return strings.TrimSpace(p) != "" } Prevention
- Validate the configured path at startup and fail fast.
- Treat an empty TOKEN_FILE env var as a hard configuration error.
- Centralize config loading so a missing field cannot silently become "".
When it happens
Trigger: Passing an unset struct field, empty env var, or zero-value string to NewTokenFileCallCredentials; a config load that silently defaulted the path to "".
Common situations: Missing TOKEN_FILE env var in the deployment; config YAML field misnamed so it deserializes to empty; refactoring that dropped the path argument.
Related errors
- credentials: audience cannot be empty
- decode error
- expected 3 parts in token
- no expiration claims
- token file is empty
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/b6d34b794819c032.
Report an issue: GitHub.
Appendix: 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 0c51461d27)