{"record":{"id":"85e97e7ab4aa469d","repo":"grpc/grpc-java","slug":"failed-to-parse-access-token-credentials-e-ge","errorCode":null,"errorMessage":"Failed to parse access token credentials: \" + e.getMessage()","messagePattern":"Failed to parse access token credentials: \" \\+ e\\.getMessage\\(\\)","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":265,"sourceCode":"        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 {\n        AccessTokenCredentials accessToken = cred.unpack(AccessTokenCredentials.class);\n        if (accessToken.getToken().isEmpty()) {\n          throw new GrpcServiceParseException(\"Missing or empty access token in call credentials.\");\n        }\n        return Optional\n            .of(new SecurityAwareAccessTokenCredentials(MoreCallCredentials.from(OAuth2Credentials\n                .create(new AccessToken(accessToken.getToken(), new Date(Long.MAX_VALUE))))));\n      } catch (InvalidProtocolBufferException e) {\n        throw new GrpcServiceParseException(\n            \"Failed to parse access token credentials: \" + e.getMessage());\n      }\n    }\n    return Optional.empty();\n  }\n\n  private static Optional<CallCredentials> extractCallCredentials(List<Any> callCredentialPlugins)\n      throws GrpcServiceParseException {\n    List<CallCredentials> creds = new ArrayList<>();\n    for (Any cred : callCredentialPlugins) {\n      Optional<CallCredentials> parsed = callCredsFromProto(cred);\n      if (parsed.isPresent()) {\n        creds.add(parsed.get());\n      }\n    }\n    return creds.stream().reduce(CompositeCallCredentials::new);\n  }\n","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L247-L283","documentation":"GrpcServiceParseException thrown when the access-token credentials embedded in an xDS cluster/CDS security configuration cannot be parsed as protobuf (InvalidProtocolBufferException). The library wraps the raw protobuf error because the token credential payload is part of a resource received from the control plane, and an unparseable payload means the resource is invalid and the service cannot be constructed.","triggerScenarios":"callCredsFromProto (invoked from `parsed`) receives a call-credentials Any/marshaled bytes whose contents do not match the expected message; the control plane sent malformed or mismatched token-credential bytes.","commonSituations":"Control plane (e.g. Istio/Envoy ADS server) sends a security config whose callCredentials typed config doesn't match the proto the client expects; version skew between control plane and grpc-xds; hand-edited or corrupted bootstrap/CDS responses.","solutions":["Inspect the xDS resource (CDS/cluster security configuration) on the control plane and fix the access-token credentials payload so it marshals the expected proto","Upgrade/downgrade the control plane or grpc-java so both sides agree on the expected credential proto version","Enable xDS client debug logging to capture the offending resource and its typeUrl","Validate the resource JSON/YAML with protoc before deploying it to the management server"],"exampleFix":"// before: sending call credentials as raw bytes in the cluster security config\nAny.newBuilder().setValue(authTokenBytes).build()\n// after: pack the correct message type\nAny.pack(TokenCredentials.newBuilder().setToken(authToken).build())","handlingStrategy":"try-catch","validationCode":"// pre-parse check before relying on xDS-delivered credentials\nif (anyCredential == null || anyCredential.getValue().isEmpty()) {\n  throw new IllegalArgumentException(\"call credentials payload is empty\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  ...buildService(...);\n} catch (GrpcServiceParseException e) {\n  if (e.getMessage().contains(\"Failed to parse access token credentials\")) {\n    // fall back to locally supplied credentials or alert on control-plane config\n    logger.log(Level.SEVERE, \"Invalid xDS token credentials\", e);\n  } else { throw e; }\n}","preventionTips":["Keep control-plane and grpc-xds proto versions in sync","Validate xDS resources (CDS) with protoc/envoy validate before publishing","Never hand-craft Any payloads; use Any.pack() with the correct message type","Pin ADS server versions in staging before rolling to production"],"tags":["xds","protobuf","config-parsing","control-plane"],"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"}