grpc/grpc-java · error · ResourceInvalidException
Listener ${proto.getName()} with invalid traffic direction:
Error message
Listener ${proto.getName()} with invalid traffic direction: ${trafficDirection} What it means
When gRPC parses a server-side Listener (for server-side xDS / HTTP filter config), it requires traffic_direction to be INBOUND or UNSPECIFIED. Any other direction (e.g. OUTBOUND) is rejected with this ResourceInvalidException naming the listener.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsListenerResource.java:152
throws ResourceInvalidException {
Set<String> certProviderInstances = null;
if (args.getBootstrapInfo() != null && args.getBootstrapInfo().certProviders() != null) {
certProviderInstances = args.getBootstrapInfo().certProviders().keySet();
}
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.");View on GitHub (pinned to 64daddc1f3)
Solutions
- Set the Listener's traffic_direction to INBOUND (or leave it UNSPECIFIED) on the management server for server workloads
- Separate inbound and outbound listener resources so outbound ones are never sent to server-side subscriptions
- Check the control plane's workload/port direction labeling (e.g. Istio sidecar scope) and fix the mismatch
- Re-push the corrected Listener so the client ACKs
Example fix
// before
listener { name: "inbound-9090" traffic_direction: OUTBOUND ... }
// after
listener { name: "inbound-9090" traffic_direction: INBOUND ... } Defensive patterns
Strategy: validation
Validate before calling
// Control-plane side: server-side listeners must be INBOUND/UNSPECIFIED
io.envoyproxy.envoy.config.core.v3.TrafficDirection dir = listener.getTrafficDirection();
if (!dir.equals(io.envoyproxy.envoy.config.core.v3.TrafficDirection.INBOUND)
&& !dir.equals(io.envoyproxy.envoy.config.core.v3.TrafficDirection.UNSPECIFIED)) {
throw new IllegalArgumentException("Listener " + listener.getName()
+ " with invalid traffic direction: " + dir);
} Try / catch
// Client side: catch direction mismatch via watcher error
@Override public void onError(Status error) {
if (error.getDescription().contains("with invalid traffic direction")) {
logger.log(WARNING, "Server listener sent with wrong direction: " + error.getDescription());
}
} Prevention
- Generate server workloads' listeners with traffic_direction INBOUND
- Keep outbound listeners on separate resource names/subscriptions from server-side LDS
- Audit control-plane direction labeling per workload port
- NACK-aware CI: run gRPC xDS interop tests against generated configs
When it happens
Trigger: A Listener resource intended for server-side consumption arrives with traffic_direction = OUTBOUND (or another non-INBOUND value); parseServerSideListener throws and the LDS update is NACKed.
Common situations: Control plane reuses an outbound listener config for a gRPC server workload; Istio sidecar resources with wrong directionality applied to a server port; copy-pasted Envoy configs keeping OUTBOUND direction.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid message type: ${unpackedMessage.getClass()}
- Could not parse HttpConnectionManager config from ApiListene
- Listener ${proto.getName()} cannot have listener_filters
- Listener ${proto.getName()} cannot have use_original_dst set
- Invalid address: Empty address is not allowed.
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/4f1e279a4be36910.
Report an issue: GitHub.