{"record":{"id":"e9b2ebdd797fde00","repo":"grpc/grpc-java","slug":"no-valid-supported-channel-credentials-found","errorCode":null,"errorMessage":"No valid supported channel_credentials found","messagePattern":"No valid supported channel_credentials found","errorType":"validation","errorClass":"GrpcServiceParseException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java","lineNumber":250,"sourceCode":"          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 {\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    }","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java#L232-L268","documentation":"extractChannelCredentials iterates every Any in channel_credentials_plugins and asks channelCredsFromProto to parse it; if none yields a ConfiguredChannelCredentials (unsupported type_url hits the default case returning Optional.empty()), the parser concludes no usable channel credentials were supplied and throws GrpcServiceParseException \"No valid supported channel_credentials found\".","triggerScenarios":"channelCreds (called by the top-level parsed method) receives a credentials config whose channel_credentials_plugins list is empty, or contains only plugins with unrecognized type_urls (channelCredsFromProto returns empty for all).","commonSituations":"Bootstrap file missing the channel_credentials section entirely; typo'd or future-version type_url not known to this grpc-java version; config generated for a language supporting credential types grpc-java does not.","solutions":["Ensure the config includes channel_credentials_plugins with a supported type (google_default, tls, xds, insecure)","Check the type_url strings against this grpc-java version's constants; fix typos or upgrade grpc-java if a newer type is needed","Validate the bootstrap JSON against the gRPC xDS bootstrap schema before feeding it to the channel builder"],"exampleFix":"// before: plugins with unknown type_url\n\"channel_credentials_plugins\": [{\"type_url\": \".../UnknownCredentials\"}]\n// after\n\"channel_credentials_plugins\": [{\"type_url\": \"type.googleapis.com/grpc.gcp.relay.GoogleDefaultCredentials\"}]\n","handlingStrategy":"validation","validationCode":"// Validate that at least one supported credentials plugin exists before building the channel\nboolean hasSupported = config.getChannelCredentialsPluginsList().stream()\n    .anyMatch(a -> KNOWN_TYPE_URLS.stream().noneMatch(u -> a.getTypeUrl().contains(u)) == false);\nif (!hasSupported) throw new IllegalArgumentException(\"No supported channel_credentials plugins\");","typeGuard":"boolean hasUsableChannelCreds(ChannelCredentialsConfig cfg) {\n  return cfg != null\n    && cfg.getChannelCredentialsPluginsCount() > 0\n    && cfg.getChannelCredentialsPluginsList().stream()\n        .anyMatch(a -> a.getTypeUrl() != null);\n}","tryCatchPattern":"try {\n  ChannelCredentials creds = XdsChannelCredentials.create(bootstrap);\n} catch (GrpcServiceParseException e) {\n  if (e.getMessage().contains(\"No valid supported channel_credentials\")) {\n    creds = InsecureChannelCredentials.create(); // or fail fast with clearer message\n  } else throw e;\n}","preventionTips":["Always populate channel_credentials in the xDS bootstrap file","Lint type_url strings against the grpc-java version's supported constants","Run bootstrap validation in CI before rollout"],"tags":["xds","grpc-java","credentials","config"],"backgroundTag":"missing-required-config-field","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"}