{"record":{"id":"9adc656cf3160d22","repo":"grpc/grpc-java","slug":"invalid-bootstrap-server-serveruri-with-chann","errorCode":null,"errorMessage":"Invalid bootstrap: server ${serverUri} with 'channel_creds' type unspecified","messagePattern":"Invalid bootstrap: server (.+?) with 'channel_creds' type unspecified","errorType":"exception","errorClass":"XdsInitializationException","httpStatus":null,"severity":"critical","filePath":"xds/src/main/java/io/grpc/xds/GrpcBootstrapperImpl.java","lineNumber":154,"sourceCode":"          \"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) {\n        throw new XdsInitializationException(\n            \"Invalid bootstrap: server \" + serverUri + \" with 'channel_creds' type unspecified\");\n      }\n      XdsCredentialsProvider provider =  XdsCredentialsRegistry.getDefaultRegistry()\n          .getProvider(type);\n      if (provider != null) {\n        Map<String, ?> config = JsonUtil.getObject(channelCreds, \"config\");\n        if (config == null) {\n          config = ImmutableMap.of();\n        }\n\n        ChannelCredentials creds = provider.newChannelCredentials(config);\n        if (creds == null) {\n          return null;\n        }\n        return ConfiguredChannelCredentials.create(creds, new JsonChannelCredsConfig(type, config));\n      }\n    }\n    return null;","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcBootstrapperImpl.java#L136-L172","documentation":"Thrown by GrpcBootstrapperImpl.parseChannelCredentials when a channel_creds entry in the bootstrap JSON has no 'type' field. The type field is mandatory because it selects which XdsCredentialsProvider parses the entry's config. Without it the credential entry is ambiguous, so bootstrap parsing fails immediately.","triggerScenarios":"Bootstrap file contains a servers[].channel_creds entry like {\"config\": {...}} with only a config object and no \"type\" key; typically from a hand-written or malformed bootstrap file.","commonSituations":"Manually editing bootstrap JSON and dropping the type key; template-generated configs with an unfilled placeholder; copying Envoy credential configs that nest type differently.","solutions":["Add the required \"type\" field to every channel_creds entry in the bootstrap file.","Validate the bootstrap JSON against the gRPC xDS bootstrap schema before deployment.","Check for JSON quoting/escaping mistakes that silently dropped the type key during templating."],"exampleFix":"// before (bootstrap.json)\n\"channel_creds\": [{\"config\": {\"cert_file\": \"ca.pem\"}}]\n// after\n\"channel_creds\": [{\"type\": \"google_default\", \"config\": {\"cert_file\": \"ca.pem\"}}]","handlingStrategy":"validation","validationCode":"// Ensure every channel_creds entry declares a type\nfor (Map<String, ?> entry : rawChannelCreds) {\n  if (JsonUtil.getString(entry, \"type\") == null) {\n    throw new IllegalArgumentException(\"channel_creds entry missing 'type'\");\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never hand-edit bootstrap channel_creds without the type key","Run a JSON schema linter over bootstrap files before deploy","Diff bootstrap changes against a known-good template"],"tags":["xds","bootstrap","missing-field","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"}