{"record":{"id":"18aa31cae61677d4","repo":"grpc/grpc-java","slug":"invalid-bootstrap-server-serveruri-channel-cr","errorCode":null,"errorMessage":"Invalid bootstrap: server ${serverUri} 'channel_creds' required","messagePattern":"Invalid bootstrap: server (.+?) 'channel_creds' required","errorType":"exception","errorClass":"XdsInitializationException","httpStatus":null,"severity":"critical","filePath":"xds/src/main/java/io/grpc/xds/GrpcBootstrapperImpl.java","lineNumber":135,"sourceCode":"  }\n\n  static synchronized BootstrapInfo defaultBootstrap() throws XdsInitializationException {\n    if (defaultBootstrap == null) {\n      if (defaultBootstrapOverride == null) {\n        defaultBootstrap = new GrpcBootstrapperImpl().bootstrap();\n      } else {\n        defaultBootstrap = new GrpcBootstrapperImpl().bootstrap(defaultBootstrapOverride);\n      }\n    }\n    return defaultBootstrap;\n  }\n\n  private static ConfiguredChannelCredentials getChannelCredentials(Map<String, ?> serverConfig,\n                                                                  String serverUri)\n      throws XdsInitializationException {\n    List<?> rawChannelCredsList = JsonUtil.getList(serverConfig, \"channel_creds\");\n    if (rawChannelCredsList == null || rawChannelCredsList.isEmpty()) {\n      throw new XdsInitializationException(\n          \"Invalid bootstrap: server \" + serverUri + \" 'channel_creds' required\");\n    }\n    ConfiguredChannelCredentials credentials =\n        parseChannelCredentials(JsonUtil.checkObjectList(rawChannelCredsList), serverUri);\n    if (credentials == null) {\n      throw new XdsInitializationException(\n          \"Server \" + serverUri + \": no supported channel credentials found\");\n    }\n    return credentials;\n  }\n\n  @Nullable\n  private static ConfiguredChannelCredentials parseChannelCredentials(List<Map<String, ?>> jsonList,\n          String serverUri)\n      throws XdsInitializationException {\n    for (Map<String, ?> channelCreds : jsonList) {\n      String type = JsonUtil.getString(channelCreds, \"type\");\n      if (type == null) {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcBootstrapperImpl.java#L117-L153","documentation":"GrpcBootstrapperImpl.getChannelCredentials reads the channel_creds array of an xds_servers entry; if the key is missing or the list is empty, it throws XdsInitializationException \"Invalid bootstrap: server <serverUri> 'channel_creds' required\". Every management server in the bootstrap must declare at least one credential type so the client can authenticate the xDS channel.","triggerScenarios":"Bootstrap JSON whose xds_servers[i] object lacks channel_creds or has \"channel_creds\": [] — thrown while building the ConfiguredChannel during bootstrap parsing.","commonSituations":"Hand-written bootstrap omitting channel_creds; config generators dropping the field; copying an example that only shows server_uri; empty array left after stripping credentials for local testing.","solutions":["Add a channel_creds array to each xds_servers entry, e.g. [{\"type\": \"google_default\"}] or [{\"type\": \"insecure\"}] for plaintext testing.","Confirm the credential type string is one the client supports (insecure, google_default, tls) and that parseChannelCredentials returns non-null.","Validate your bootstrap JSON against the gRPC xDS bootstrap schema before deploying.","If channel_creds is present but still failing, check the next error path ('No valid credentials found') for unsupported types."],"exampleFix":"// before\n{ \"xds_servers\": [ { \"server_uri\": \"xds.example.com:443\" } ] }\n// after\n{ \"xds_servers\": [ { \"server_uri\": \"xds.example.com:443\", \"channel_creds\": [ { \"type\": \"google_default\" } ] } ] }","handlingStrategy":"validation","validationCode":"for (Object s : (List<?>) boot.get(\"xds_servers\")) {\n  Map<?, ?> server = (Map<?, ?>) s;\n  Object creds = server.get(\"channel_creds\");\n  if (!(creds instanceof List<?>) || ((List<?>) creds).isEmpty()) {\n    throw new IllegalArgumentException(\"channel_creds missing for server \" + server.get(\"server_uri\"));\n  }\n}","typeGuard":null,"tryCatchPattern":"try { /* init xDS */ } catch (XdsInitializationException e) { if (e.getMessage().contains(\"'channel_creds' required\")) { log.error(\"Add channel_creds to xds_servers entry\"); } }","preventionTips":["Include a channel_creds array (e.g. [{\"type\":\"google_default\"}]) in every xds_servers entry","Never strip channel_creds when templating bootstrap for production","Validate the bootstrap against the gRPC xDS bootstrap schema in CI"],"tags":["xds","bootstrap","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"}