grpc/grpc-java · error · ResourceInvalidException
Listener ${proto.getName()} cannot have listener_filters
Error message
Listener ${proto.getName()} cannot have listener_filters What it means
gRPC server-side Listener parsing does not support Envoy's listener_filters (used e.g. for TLS inspector). If a Listener resource contains any listener_filters, it is rejected with this error naming the listener.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsListenerResource.java:156
}
return LdsUpdate.forTcpListener(parseServerSideListener(proto,
(TlsContextManager) args.getSecurityConfig(),
filterRegistry, certProviderInstances, args));
}
@VisibleForTesting
static EnvoyServerProtoData.Listener parseServerSideListener(
Listener proto, TlsContextManager tlsContextManager,
FilterRegistry filterRegistry, Set<String> certProviderInstances, XdsResourceType.Args args)
throws ResourceInvalidException {
TrafficDirection trafficDirection = proto.getTrafficDirection();
if (!trafficDirection.equals(TrafficDirection.INBOUND)
&& !trafficDirection.equals(TrafficDirection.UNSPECIFIED)) {
throw new ResourceInvalidException(
"Listener " + proto.getName() + " with invalid traffic direction: " + trafficDirection);
}
if (!proto.getListenerFiltersList().isEmpty()) {
throw new ResourceInvalidException(
"Listener " + proto.getName() + " cannot have listener_filters");
}
if (proto.hasUseOriginalDst()) {
throw new ResourceInvalidException(
"Listener " + proto.getName() + " cannot have use_original_dst set to true");
}
String address = null;
SocketAddress socketAddress = null;
if (proto.getAddress().hasSocketAddress()) {
socketAddress = proto.getAddress().getSocketAddress();
address = socketAddress.getAddress();
if (address.isEmpty()) {
throw new ResourceInvalidException("Invalid address: Empty address is not allowed.");
}
switch (socketAddress.getPortSpecifierCase()) {
case NAMED_PORT:
throw new ResourceInvalidException("NAMED_PORT is not supported in gRPC.");View on GitHub (pinned to 64daddc1f3)
Solutions
- Remove listener_filters from Listeners targeted at gRPC servers (gRPC handles TLS via its own security config)
- Reconfigure the control plane so gRPC server listeners contain only filter_chains gRPC supports
- If TLS inspection is required, rely on gRPC's tls_context/chain-level config instead of Envoy filter chains
- Re-push the corrected Listener resource so the update is ACKed
Example fix
// before
listener { name: "inbound-9090" listener_filters { name: "envoy.filters.listener.tls_inspector" } ... }
// after
listener { name: "inbound-9090" ... } Defensive patterns
Strategy: validation
Validate before calling
// Control-plane side: reject listener_filters before publishing to gRPC servers
if (!listener.getListenerFiltersList().isEmpty()) {
throw new IllegalArgumentException("Listener " + listener.getName()
+ " cannot have listener_filters");
} Try / catch
// Client side: detect unsupported listener_filters from watcher errors
@Override public void onError(Status error) {
if (error.getDescription().contains("cannot have listener_filters")) {
logger.log(WARNING, "Listener uses unsupported listener_filters: " + error.getDescription());
}
} Prevention
- Strip Envoy-only listener filters (e.g. tls_inspector) from listeners sent to gRPC servers
- Handle TLS via gRPC security configuration (tls_context/SDS), not listener filters
- Template server listeners specifically for gRPC rather than reusing Envoy templates
- Run xDS interop/conformance tests on generated listener configs
When it happens
Trigger: A Listener sent to a gRPC server via LDS has a non-empty listener_filters list (commonly listener_filters containing envoy.filters.listener.tls_inspector); parseServerSideListener throws before further processing.
Common situations: Envoy-derived configurations (e.g. from an Envoy-based control plane) that rely on tls_inspector to sniff protocol; Istio/other meshes emitting their standard listener filter chain to gRPC server workloads; copy-pasted Envoy static configs.
Related errors
- Listener ${proto.getName()} cannot have use_original_dst set
- Invalid message type: ${unpackedMessage.getClass()}
- Could not parse HttpConnectionManager config from ApiListene
- Listener ${proto.getName()} with invalid traffic direction:
- Invalid address: Empty address is not allowed.
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/4e50364ba261aa78.
Report an issue: GitHub.