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

  1. Set the Listener's traffic_direction to INBOUND (or leave it UNSPECIFIED) on the management server for server workloads
  2. Separate inbound and outbound listener resources so outbound ones are never sent to server-side subscriptions
  3. Check the control plane's workload/port direction labeling (e.g. Istio sidecar scope) and fix the mismatch
  4. 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

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


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