openzipkin/zipkin · critical · IllegalArgumentException

No valid endpoints found in ES hosts: {hosts}

Error message

No valid endpoints found in ES hosts: {hosts}

What it means

InitialEndpointSupplier throws IllegalArgumentException ('No valid endpoints found in ES hosts: {hosts}') when after parsing the configured ES hosts list, zero usable endpoints were produced. Hosts entries are split and parsed into Armeria endpoints (IP, localhost, or DNS-resolvable names); if every entry fails parsing or the list is empty after filtering, the supplier refuses to build an empty endpoint group.

Source

Thrown at zipkin-server/src/main/java/zipkin2/server/internal/elasticsearch/InitialEndpointSupplier.java:70

      int port = getPort(url);

      if (port == 9300) {
        LOGGER.warn("Native transport no longer supported. Changing {} to http port 9200", host);
        port = 9200;
      }

      if (isIpAddress(host) || host.equals("localhost")) {
        endpointGroups.add(EndpointGroup.of(Endpoint.of(host, port)));
      } else {
        // A host that isn't an IP may resolve to multiple IP addresses, so we use a endpoint
        // group to round-robin over them. Users can mix addresses that resolve to multiple IPs
        // with single IPs freely, they'll all get used.
        endpointGroups.add(DnsAddressEndpointGroup.builder(host).port(port).build());
      }
    }

    if (endpointGroups.isEmpty()) {
      throw new IllegalArgumentException("No valid endpoints found in ES hosts: " + hosts);
    }

    return EndpointGroup.of(endpointGroups);
  }

  int getPort(URI url) {
    int port = url.getPort();
    return port != -1 ? port : sessionProtocol.defaultPort();
  }

  static boolean isIpAddress(String address) {
    return zipkin2.Endpoint.newBuilder().parseIp(address);
  }

  @Override public String toString() {
    return hosts;
  }
}

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Set hosts to at least one valid endpoint, e.g. zipkin.storage.elasticsearch.hosts=http://elasticsearch:9200
  2. Check each comma-separated entry has scheme://host:port form and no stray whitespace
  3. If using env vars, confirm ES hosts variable is set in the actual runtime environment

Example fix

# before
zipkin.storage.elasticsearch.hosts=

# after
zipkin.storage.elasticsearch.hosts=http://elasticsearch:9200
Defensive patterns

Strategy: validation

Validate before calling

String hosts = requiredEnv("ES_HOSTS");
if (hosts == null || hosts.isBlank() || hosts.chars().allMatch(c -> c == ',')) {
  throw new IllegalStateException("ES_HOSTS must contain at least one scheme://host:port entry");
}

Prevention

When it happens

Trigger: Setting zipkin.storage.elasticsearch.hosts to an empty string, or to entries whose scheme/host/port cannot be parsed (e.g. 'http://', '://es:9200', entries with whitespace or invalid characters), so endpointGroups ends up empty at the check.

Common situations: Empty ES_HOSTS env var in a container, malformed URLs from templating, a hosts string of only delimiters, or a config typo like 'http//es:9200' silently skipping all entries.

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/61e76f574a7fc79c. Report an issue: GitHub.