{"record":{"id":"d0535283cacbd143","repo":"grpc/grpc-java","slug":"invalid-bootstrap-xds-servers-is-empty","errorCode":null,"errorMessage":"Invalid bootstrap: 'xds_servers' is empty","messagePattern":"Invalid bootstrap: 'xds_servers' is empty","errorType":"exception","errorClass":"XdsInitializationException","httpStatus":null,"severity":"critical","filePath":"xds/src/main/java/io/grpc/xds/GrpcBootstrapperImpl.java","lineNumber":60,"sourceCode":"  private static final String BOOTSTRAP_CONFIG_SYS_PROPERTY = \"io.grpc.xds.bootstrapConfig\";\n  @VisibleForTesting\n  String bootstrapPathFromEnvVar = System.getenv(BOOTSTRAP_PATH_SYS_ENV_VAR);\n  @VisibleForTesting\n  String bootstrapPathFromSysProp = System.getProperty(BOOTSTRAP_PATH_SYS_PROPERTY);\n  @VisibleForTesting\n  String bootstrapConfigFromEnvVar = System.getenv(BOOTSTRAP_CONFIG_SYS_ENV_VAR);\n  @VisibleForTesting\n  String bootstrapConfigFromSysProp = System.getProperty(BOOTSTRAP_CONFIG_SYS_PROPERTY);\n\n  GrpcBootstrapperImpl() {\n    super();\n  }\n\n  @Override\n  public BootstrapInfo bootstrap(Map<String, ?> rawData) throws XdsInitializationException {\n    BootstrapInfo info = super.bootstrap(rawData);\n    if (info.servers().isEmpty()) {\n      throw new XdsInitializationException(\"Invalid bootstrap: 'xds_servers' is empty\");\n    }\n    return info;\n  }\n\n  /**\n   * Gets the bootstrap config as JSON. Searches the config (or file of config) with the\n   * following order:\n   *\n   * <ol>\n   *   <li>A filesystem path defined by environment variable \"GRPC_XDS_BOOTSTRAP\"</li>\n   *   <li>A filesystem path defined by Java System Property \"io.grpc.xds.bootstrap\"</li>\n   *   <li>Environment variable value of \"GRPC_XDS_BOOTSTRAP_CONFIG\"</li>\n   *   <li>Java System Property value of \"io.grpc.xds.bootstrapConfig\"</li>\n   * </ol>\n   */\n  @Override\n  protected String getJsonContent() throws XdsInitializationException, IOException {\n    String jsonContent;","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/GrpcBootstrapperImpl.java#L42-L78","documentation":"GrpcBootstrapperImpl.bootstrap parses the xDS bootstrap and rejects the result when the servers list is empty, throwing XdsInitializationException \"Invalid bootstrap: 'xds_servers' is empty\". A bootstrap with no management servers leaves the client unable to establish any xDS stream, so it refuses to initialize.","triggerScenarios":"Calling bootstrap(rawData) — or initializing the xDS name resolver/channel — where the resolved bootstrap JSON's xds_servers array is missing or resolves to an empty list.","commonSituations":"Bootstrap file/env var containing \"xds_servers\": []; typo like \"xds_server\"; config merged/overwritten so the array is dropped; control-plane templates rendering no servers.","solutions":["Add at least one entry to xds_servers in your bootstrap JSON with a valid server_uri and channel_creds.","Check for key typos (xds_server vs xds_servers) or JSON that overrides the array with an empty one.","Print the bootstrap JSON (GrpcBootstrapperImpl bootstrapDump / logs) and confirm the servers list is populated.","If using a file, ensure GRPC_XDS_BOOTSTRAP points to the intended file and the file was fully written."],"exampleFix":"// before\n{ \"xds_servers\": [] }\n// after\n{ \"xds_servers\": [ { \"server_uri\": \"xds.example.com:443\", \"channel_creds\": [ { \"type\": \"google_default\" } ] } ] }","handlingStrategy":"validation","validationCode":"Map<String, ?> boot = /* parsed bootstrap JSON */;\nList<?> servers = (List<?>) boot.get(\"xds_servers\");\nif (servers == null || servers.isEmpty()) throw new IllegalArgumentException(\"xds_servers must be non-empty\");","typeGuard":null,"tryCatchPattern":"try { /* init xDS */ } catch (XdsInitializationException e) { if (e.getMessage().contains(\"'xds_servers' is empty\")) { log.error(\"Bootstrap has no management servers\"); } }","preventionTips":["Validate bootstrap JSON schema before startup","Watch for key typos and empty-array overwrites in config pipelines","Dump the effective bootstrap at startup for verification"],"tags":["xds","bootstrap","config","empty-list"],"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"}