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
- Inspect the LDS listener resource and make filter chain match predicates mutually exclusive (distinct destination_ports/prefix_ranges/source ranges).
- File/verify a bug against grpc-java if ClientXdsClient's uniqueness validation should have rejected this listener.
- Update both client and management server to versions with consistent filter-chain validation.
- 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
- Make filter_chain match predicates mutually exclusive in the listener config
- Upgrade grpc-java/management server together so chain uniqueness validation and matching stay consistent
- Reproduce with a dump of the listener resource when it occurs
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
- NAMED_PORT is not supported in gRPC.
- FilterChain ${filterChainName} should contain exact one Http
- FilterChain ${filterChainName} contains filter ${l4Filter.ge
- FilterChain ${filterChainName} contains filter ${l4Filter.ge
- Not implemented
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/b3910e221f4a89fe.
Report an issue: GitHub.