{"record":{"id":"f4523db77648af7c","repo":"grpc/grpc-go","slug":"failed-to-create-jwt-call-credentials-v","errorCode":null,"errorMessage":"failed to create JWT call credentials: %v","messagePattern":"failed to create JWT call credentials: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/bootstrap/jwtcreds/call_creds.go","lineNumber":51,"sourceCode":"// config must match the structure specified in gRFC A97.\n//\n// The caller is expected to invoke the cancel function when they are done using\n// the returned call creds. This cancel function is idempotent.\nfunc NewCallCredentials(configJSON json.RawMessage) (c credentials.PerRPCCredentials, cancel func(), err error) {\n\tvar cfg struct {\n\t\tJWTTokenFile string `json:\"jwt_token_file\"`\n\t}\n\temptyFn := func() {}\n\n\tif err := json.Unmarshal(configJSON, &cfg); err != nil {\n\t\treturn nil, emptyFn, fmt.Errorf(\"failed to unmarshal JWT call credentials config: %v\", err)\n\t}\n\tif cfg.JWTTokenFile == \"\" {\n\t\treturn nil, emptyFn, fmt.Errorf(\"jwt_token_file is required in JWT call credentials config\")\n\t}\n\tcallCreds, err := jwt.NewTokenFileCallCredentials(cfg.JWTTokenFile)\n\tif err != nil {\n\t\treturn nil, emptyFn, fmt.Errorf(\"failed to create JWT call credentials: %v\", err)\n\t}\n\treturn callCreds, emptyFn, nil\n}\n","sourceCodeStart":33,"sourceCodeEnd":55,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/bootstrap/jwtcreds/call_creds.go#L33-L55","documentation":"After validating the jwt_token_file path is non-empty, NewCallCredentials delegates to jwt.NewTokenFileCallCredentials (call_creds.go:49-51). If that function cannot open or parse the token file, it returns an error that is wrapped here. The underlying cause (e.g. file not found, invalid JWT format) is included.","triggerScenarios":"The jwt_token_file path is set but the file does not exist, is not readable, or does not contain a valid JWT. jwt.NewTokenFileCallCredentials reads the file and validates the token structure.","commonSituations":"The token file path is correct in config but the volume/secret was not mounted; the file exists but is empty or contains a placeholder string; the JWT expired-formatted token is malformed; permission mismatch between the injecting process and the consumer UID.","solutions":["Confirm the token file exists at the configured path and is readable by the process.","Validate the file content is a well-formed JWT (three dot-separated base64 segments).","Check that the token-injecting sidecar or projected service-account token volume is mounted before the client initializes.","Inspect the wrapped error (%v) to distinguish file-not-found from parse errors."],"exampleFix":"// before: jwt_token_file points to a path that doesn't exist yet\n// after: ensure the projected token volume is mounted:\n//   volumes:\n//     - name: jwt-token\n//       projected:\n//         sources:\n//           - serviceAccountToken:\n//               path: token\n//               audience: xds-server","handlingStrategy":"validation","validationCode":"// Verify the JWT token file exists and is a plausible JWT before creating creds.\nfunc ensureJWTTokenFileReadable(path string) error {\n    b, err := os.ReadFile(path)\n    if err != nil {\n        return err\n    }\n    parts := strings.Split(strings.TrimSpace(string(b)), \".\")\n    if len(parts) != 3 {\n        return fmt.Errorf(\"%s does not look like a JWT (expected 3 dot-separated segments)\", path)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Capture and log the wrapped cause distinctly.\nc, cancel, err := jwtcreds.NewCallCredentials(cfg)\nif err != nil {\n    return fmt.Errorf(\"jwt call creds unavailable; check token file: %w\", err)\n}","preventionTips":["Mount the projected token volume and verify readability before client init.","Distinguish file-not-found from parse errors by inspecting the wrapped error.","In Kubernetes, use a projected serviceAccountToken volume for reliable JWT injection."],"tags":["xds","bootstrap","jwt","credentials","filesystem","grpc"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}