{"record":{"id":"11064f96c280dc96","repo":"grpc/grpc-go","slug":"jwt-token-file-is-required-in-jwt-call-credentials","errorCode":null,"errorMessage":"jwt_token_file is required in JWT call credentials config","messagePattern":"jwt_token_file is required in JWT call credentials config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/bootstrap/jwtcreds/call_creds.go","lineNumber":47,"sourceCode":"\t\"google.golang.org/grpc/credentials/jwt\"\n)\n\n// NewCallCredentials returns a new JWT token based call credentials. The input\n// 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":29,"sourceCodeEnd":55,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/bootstrap/jwtcreds/call_creds.go#L29-L55","documentation":"Returned by jwtcreds.NewCallCredentials when the config unmarshalled successfully but jwt_token_file is empty. The token file path is mandatory for JWT call credentials.","triggerScenarios":"Triggered at call_creds.go:47 when cfg.JWTTokenFile == \"\" after parsing. The field is either omitted or explicitly empty.","commonSituations":"jwt_token_file field omitted from the call_creds config; field present but empty; templating left the value blank.","solutions":["Provide a non-empty jwt_token_file path in the call_creds config.","If JWT call creds are not needed, remove the call_creds entry or disable the call-creds feature flag.","Ensure the bootstrap generator/template fills this field."],"exampleFix":"// before\n{\"type\":\"jwt\",\"config\":{}}\n\n// after\n{\"type\":\"jwt\",\"config\":{\"jwt_token_file\":\"/var/secrets/token.jwt\"}}","handlingStrategy":"validation","validationCode":"// Ensure jwt_token_file is non-empty.\nfunc requireJWTTokenFile(raw json.RawMessage) error {\n    var cfg struct {\n        JWTTokenFile string `json:\"jwt_token_file\"`\n    }\n    _ = json.Unmarshal(raw, &cfg)\n    if cfg.JWTTokenFile == \"\" {\n        return fmt.Errorf(\"jwt_token_file is required\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := jwtcreds.NewCallCredentials(cfg); err != nil {\n    if strings.Contains(err.Error(), \"jwt_token_file is required\") {\n        // set jwt_token_file before retrying.\n    }\n}","preventionTips":["Treat jwt_token_file as mandatory in your config template.","Disable the call-creds feature flag if JWT creds are unused.","Fail the deploy if the token file path is empty."],"tags":["grpc","xds","jwt","call-credentials","config","go"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}