grpc/grpc-java · error · ResourceInvalidException

HttpConnectionManager with original_ip_detection_extensions

Error message

HttpConnectionManager with original_ip_detection_extensions unsupported

What it means

gRPC xDS does not support original_ip_detection_extensions on the HttpConnectionManager (custom IP detection via extension filters). Any non-empty list makes the resource invalid and XdsListenerResource throws ResourceInvalidException, NACKing the Listener.

Source

Thrown at xds/src/main/java/io/grpc/xds/XdsListenerResource.java:503

        prefixRanges.build(),
        ImmutableList.copyOf(proto.getApplicationProtocolsList()),
        sourcePrefixRanges.build(),
        sourceType,
        ImmutableList.copyOf(proto.getSourcePortsList()),
        ImmutableList.copyOf(proto.getServerNamesList()),
        proto.getTransportProtocol());
  }

  @VisibleForTesting
  static io.grpc.xds.HttpConnectionManager parseHttpConnectionManager(
      HttpConnectionManager proto, FilterRegistry filterRegistry,
      boolean isForClient, XdsResourceType.Args args) throws ResourceInvalidException {
    if (proto.getXffNumTrustedHops() != 0) {
      throw new ResourceInvalidException(
          "HttpConnectionManager with xff_num_trusted_hops unsupported");
    }
    if (!proto.getOriginalIpDetectionExtensionsList().isEmpty()) {
      throw new ResourceInvalidException("HttpConnectionManager with "
          + "original_ip_detection_extensions unsupported");
    }
    // Obtain max_stream_duration from Http Protocol Options.
    long maxStreamDuration = 0;
    if (proto.hasCommonHttpProtocolOptions()) {
      HttpProtocolOptions options = proto.getCommonHttpProtocolOptions();
      if (options.hasMaxStreamDuration()) {
        maxStreamDuration = Durations.toNanos(options.getMaxStreamDuration());
      }
    }

    // Parse http filters.
    if (proto.getHttpFiltersList().isEmpty()) {
      throw new ResourceInvalidException("Missing HttpFilter in HttpConnectionManager.");
    }
    List<Filter.NamedFilterConfig> filterConfigs = new ArrayList<>();
    Set<String> names = new HashSet<>();
    for (int i = 0; i < proto.getHttpFiltersCount(); i++) {

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Remove original_ip_detection_extensions from the http_connection_manager.
  2. Perform custom client IP detection at the Envoy proxy layer rather than in resources consumed by gRPC.
  3. Upgrade gRPC and check release notes in case support for this field was added.

Example fix

// before
http_connection_manager:
  original_ip_detection_extensions: [{ name: envoy.http.original_ip_detection.custom_header }]
// after
http_connection_manager: {}
Defensive patterns

Strategy: validation

Validate before calling

if (!hcm.getOriginalIpDetectionExtensionsList().isEmpty()) {
  throw new IllegalArgumentException("original_ip_detection_extensions unsupported by grpc xds");
}

Try / catch

try { applyResource(listener) } catch (ResourceInvalidException e) { if (e.getMessage().contains("original_ip_detection_extensions")) resubmitWithoutExtensions(); }

Prevention

When it happens

Trigger: Listener's http_connection_manager has one or more entries in original_ip_detection_extensions, checked immediately after the xff_num_trusted_hops check in parseHttpConnectionManager.

Common situations: Envoy configs using custom header/IP detection extensions (e.g. for geo routing) reused as gRPC xDS listener resources, or control-plane generators that always emit detection extensions for cloud load balancer setups.

Related errors


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