grpc/grpc-java · critical · IllegalStateException

Found more than one matching filter chains. This should not

Error message

Found more than one matching filter chains. This should not be possible as ClientXdsClient validated the chains for uniqueness.

What it means

FilterChainMatchingProtocolNegotiators.select filters listener filter chains by destination/source IP and port; after full filtering more than one chain remained, which contradicts ClientXdsClient's uniqueness validation, so an IllegalStateException is thrown. This is an internal invariant violation: by design at most one filter chain should match a connection.

Source

Thrown at xds/src/main/java/io/grpc/xds/FilterChainMatchingProtocolNegotiators.java:189

      }

      /**
       * Throws IllegalStateException when no exact one match, and we should close the connection.
       */
      SelectedConfig select(InetSocketAddress localAddr, InetSocketAddress remoteAddr) {
        Collection<FilterChain> filterChains = routingConfigs.keySet();
        filterChains = filterOnDestinationPort(filterChains);
        filterChains = filterOnIpAddress(filterChains, localAddr.getAddress(), true);
        filterChains = filterOnServerNames(filterChains);
        filterChains = filterOnTransportProtocol(filterChains);
        filterChains = filterOnApplicationProtocols(filterChains);
        filterChains =
                filterOnSourceType(filterChains, remoteAddr.getAddress(), localAddr.getAddress());
        filterChains = filterOnIpAddress(filterChains, remoteAddr.getAddress(), false);
        filterChains = filterOnSourcePort(filterChains, remoteAddr.getPort());

        if (filterChains.size() > 1) {
          throw new IllegalStateException("Found more than one matching filter chains. This should "
              + "not be possible as ClientXdsClient validated the chains for uniqueness.");
        }
        if (filterChains.size() == 1) {
          FilterChain selected = Iterables.getOnlyElement(filterChains);
          return new SelectedConfig(
                  routingConfigs.get(selected), selected.sslContextProviderSupplier());
        }
        if (defaultRoutingConfig.get() != null) {
          return new SelectedConfig(defaultRoutingConfig, defaultSslContextProviderSupplier);
        }
        return null;
      }

      // reject if filer-chain-match has non-empty application_protocols
      private static Collection<FilterChain> filterOnApplicationProtocols(
              Collection<FilterChain> filterChains) {
        ArrayList<FilterChain> filtered = new ArrayList<>(filterChains.size());
        for (FilterChain filterChain : filterChains) {

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Inspect the LDS listener resource and make filter chain match predicates mutually exclusive (distinct destination_ports/prefix_ranges/source ranges).
  2. File/verify a bug against grpc-java if ClientXdsClient's uniqueness validation should have rejected this listener.
  3. Update both client and management server to versions with consistent filter-chain validation.
  4. Dump the listener config (Envoy admin / Istio debug) and compare the overlapping chains.

Example fix

// before (two overlapping chains)
{"filterChainMatch": {"destinationPort": 8080}},
{"filterChainMatch": {"destinationPort": 8080}}
// after — distinct predicates
{"filterChainMatch": {"destinationPort": 8080, "prefixRanges": [{"addressPrefix": "10.0.0.0", "prefixLen": 8}]}},
{"filterChainMatch": {"destinationPort": 8080, "prefixRanges": [{"addressPrefix": "10.1.0.0", "prefixLen": 16}]}}
Defensive patterns

Strategy: try-catch

Try / catch

try { /* connect via xDS */ } catch (IllegalStateException e) {
  if (e.getMessage().contains("more than one matching filter chains")) {
    log.error("Listener has overlapping filter chains; fix LDS match predicates");
  }
}

Prevention

When it happens

Trigger: Receiving an LDS listener whose filter chains are indistinguishable after matching on destination port/IP, source IP/port and source type — i.e. ClientXdsClient accepted duplicate/multiple matching chains for the same connection predicate.

Common situations: Control plane sends overlapping filter_chain match predicates (e.g. two chains with the same destination port and no distinguishing prefix ranges); ClientXdsClient validation not catching an overlap the runtime matcher exposes; version skew between validation and matching logic.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/b3910e221f4a89fe. Report an issue: GitHub.