{"record":{"id":"50ec5b5279fa1e66","repo":"grpc/grpc-java","slug":"failed-to-parse-channel-credentials-e-getmess","errorCode":null,"errorMessage":"Failed to parse channel credentials: \" + e.getMessage()","messagePattern":"Failed to parse channel credentials: \" \\+ e\\.getMessage\\(\\)","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":238,"sourceCode":"          }\n          return Optional.of(ConfiguredChannelCredentials.create(\n              XdsChannelCredentials.create(fallbackCreds.get().channelCredentials()),\n              new ProtoChannelCredsConfig(typeUrl, cred)));\n        case LOCAL_CREDENTIALS_TYPE_URL:\n          throw new GrpcServiceParseException(\n              \"LocalCredentials are not supported in grpc-java. \"\n                  + \"See https://github.com/grpc/grpc-java/issues/8928\");\n        case TLS_CREDENTIALS_TYPE_URL:\n          // For this PR, we establish this structural skeleton,\n          // but throw an GrpcServiceParseException until the exact stream conversions are\n          // merged.\n          throw new GrpcServiceParseException(\n              \"TlsCredentials input stream construction pending.\");\n        default:\n          return Optional.empty();\n      }\n    } catch (InvalidProtocolBufferException e) {\n      throw new GrpcServiceParseException(\"Failed to parse channel credentials: \" + e.getMessage());\n    }\n  }\n\n  private static ConfiguredChannelCredentials extractChannelCredentials(\n      List<Any> channelCredentialPlugins) throws GrpcServiceParseException {\n    for (Any cred : channelCredentialPlugins) {\n      Optional<ConfiguredChannelCredentials> parsed = channelCredsFromProto(cred);\n      if (parsed.isPresent()) {\n        return parsed.get();\n      }\n    }\n    throw new GrpcServiceParseException(\"No valid supported channel_credentials found\");\n  }\n\n  private static Optional<CallCredentials> callCredsFromProto(Any cred)\n      throws GrpcServiceParseException {\n    if (cred.is(AccessTokenCredentials.class)) {\n      try {","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L220-L256","documentation":"While parsing a channel-credentials plugin proto, an InvalidProtocolBufferException was raised (malformed bytes/fields inside the Any payload), and channelCredsFromProto rethrows it as GrpcServiceParseException with the message \"Failed to parse channel credentials: \" plus the cause text. It signals the credentials config data itself is corrupt or not the expected message type.","triggerScenarios":"channelCredsFromProto calls cred.unpack(...) (or value parsing) inside the try block and the Any payload cannot be deserialized into the expected credentials message; reached via fallbackCreds or parsed from extractChannelCredentials.","commonSituations":"Hand-edited bootstrap JSON with wrong base64 for the credentials value; control plane serializing an unexpected message type under a credentials type_url; version skew where proto definitions differ between producer and grpc-java.","solutions":["Fix the credentials Any payload so it decodes to the expected message for its type_url (read the embedded cause message for the exact decode failure)","Regenerate the bootstrap/config from a trusted template or the control plane rather than hand-editing","Verify proto versions match between the config producer and grpc-java's xds protos"],"exampleFix":"// before (corrupt payload)\n{\"type_url\": \".../TlsCredentials\", \"value\": \"!!!not-base64!!!\"}\n// after\n{\"type_url\": \".../TlsCredentials\", \"value\": \"Cg4KC...\"}\n","handlingStrategy":"validation","validationCode":"// Validate the Any payload decodes before handing it to the parser\ntry {\n  if (cred.is(TlsCredentials.class)) cred.unpack(TlsCredentials.class);\n} catch (InvalidProtocolBufferException e) {\n  throw new IllegalArgumentException(\"Corrupt credentials payload: \" + e.getMessage());\n}","typeGuard":"boolean isDecodableCredentials(Any cred) {\n  try { cred.unpack(TlsCredentials.class); return true; }\n  catch (InvalidProtocolBufferException e) { return false; }\n}","tryCatchPattern":"try {\n  channel = XdsChannelCredentials.create(config);\n} catch (GrpcServiceParseException e) {\n  if (e.getMessage().startsWith(\"Failed to parse channel credentials\")) {\n    log.error(\"Bad credentials proto: {}\", e.getMessage()); // regenerate config\n  } else throw e;\n}","preventionTips":["Generate bootstrap files programmatically, never hand-edit base64 blobs","Keep xds proto definitions in sync between config producer and grpc-java","Validate bootstrap JSON against the gRPC xDS bootstrap schema at deploy time"],"tags":["xds","grpc-java","protobuf","parsing"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}