grpc/grpc-go · error
failed to create JWT call credentials
Error message
failed to create JWT call credentials: %v
What it means
Returned by jwtcreds.NewCallCredentials when jwt.NewTokenFileCallCredentials fails for the supplied file path. The underlying error from the JWT package is wrapped.
Solutions
- Verify the path exists and is readable: ls -l /var/secrets/token.jwt.
- Inspect the underlying %v error to distinguish missing-file vs parse failure.
- Confirm the file contents is a valid compact-serialization JWT (three base64url segments separated by '.').
- In containers, ensure the secret holding the token is mounted at that path.
Example fix
# before: file missing or unreadable
{"jwt_token_file":"/var/secrets/token.jwt"}
# ls /var/secrets/token.jwt -> No such file
# after: create/mount the token
echo -n 'eyJhbGciOi...signature' > /var/secrets/token.jwt
chmod 600 /var/secrets/token.jwt Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight check of the JWT token file before bootstrap.
func checkJWTTokenFile(path string) error {
fi, err := os.Stat(path)
if err != nil {
return fmt.Errorf("jwt token file: %w", err)
}
if fi.Size() == 0 {
return fmt.Errorf("jwt token file is empty")
}
return nil
} Try / catch
if _, _, err := jwtcreds.NewCallCredentials(cfg); err != nil {
if strings.Contains(err.Error(), "failed to create JWT call credentials") {
// verify file exists/permissions/contents, then retry.
}
} Prevention
- Mount the JWT token as a secret at a fixed path.
- Add a startup check that the token file is non-empty.
- Refresh rotated tokens via a mounted secret, not a one-shot copy.
When it happens
Trigger: Triggered at call_creds.go:51 when jwt.NewTokenFileCallCredentials(cfg.JWTTokenFile) errors. Typically the file cannot be read or cannot be parsed.
Common situations: Token file does not exist at the given path; permission denied; file is empty or not a valid JWT (wrong number of segments, bad base64); path is correct in dev but not mounted in the container.
Related errors
- failed to build call credentials from bootstrap for
- failed to unmarshal JWT call credentials config
- jwt_token_file is required in JWT call credentials config
- token file access error
- xds: failed to read bootstrap config from file
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/f4523db77648af7c.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/bootstrap/jwtcreds/call_creds.go:51
// config must match the structure specified in gRFC A97.
//
// The caller is expected to invoke the cancel function when they are done using
// the returned call creds. This cancel function is idempotent.
func NewCallCredentials(configJSON json.RawMessage) (c credentials.PerRPCCredentials, cancel func(), err error) {
var cfg struct {
JWTTokenFile string `json:"jwt_token_file"`
}
emptyFn := func() {}
if err := json.Unmarshal(configJSON, &cfg); err != nil {
return nil, emptyFn, fmt.Errorf("failed to unmarshal JWT call credentials config: %v", err)
}
if cfg.JWTTokenFile == "" {
return nil, emptyFn, fmt.Errorf("jwt_token_file is required in JWT call credentials config")
}
callCreds, err := jwt.NewTokenFileCallCredentials(cfg.JWTTokenFile)
if err != nil {
return nil, emptyFn, fmt.Errorf("failed to create JWT call credentials: %v", err)
}
return callCreds, emptyFn, nil
}
View on GitHub (pinned to 0c51461d27)