grpc/grpc-java · error · ResourceInvalidException

HttpConnectionManager contains invalid RDS: must specify…

Error message

HttpConnectionManager contains invalid RDS: must specify ADS or self ConfigSource

What it means

When an HttpConnectionManager uses RDS, the config_source must specify either ADS or SELF as the discovery mechanism. A config_source pointing at a non-ADS, non-SELF source (e.g. a path-based or gRPC API source) is rejected because this gRPC xDS implementation only supports ADS or self discovery for route configurations.

Solutions

  1. Change the Rds config_source to ads: {}
  2. Or use config_source { self: {} } if the listener and routes come from the same server
  3. Ensure the client connects over ADS (grpc xDS bootstrap with ADS servers) so the source is valid

Example fix

// before
rds: {
  route_config_name: "routes"
  config_source: { path: "/etc/envoy/routes.pb" }
}
// after
rds: {
  route_config_name: "routes"
  config_source: { ads: {} }
}
Defensive patterns

Strategy: validation

Validate before calling

// Java (proto): ensure config_source is ADS or SELF
Rds rds = hcm.getRds();
if (rds.hasConfigSource()
    && !rds.getConfigSource().hasAds()
    && !rds.getConfigSource().hasSelf()) {
  throw new IllegalArgumentException("RDS config_source must be ads or self");
}

Try / catch

try {
  xdsClient.watchResource(LISTENER, name, listenerWatcher);
} catch (ResourceInvalidException e) {
  log.error("Unsupported RDS config_source: {}", e.getMessage());
}

Prevention

When it happens

Trigger: parseHttpConnectionManager: rds.hasConfigSource() is true but neither config_source.hasAds() nor config_source.hasSelf() is set (e.g. api_type GRPC or path-based config_source).

Common situations: Configs written for Envoy's file-based (path) config source or a separate gRPC management server being reused with gRPC xDS; copy-pasted Envoy bootstrap config_source blocks.

Related errors


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

Appendix: source

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

      }
      filterConfigs.add(new Filter.NamedFilterConfig(filterName, filterConfig.getStruct()));
    }

    // Parse inlined RouteConfiguration or RDS.
    if (proto.hasRouteConfig()) {
      List<VirtualHost> virtualHosts = extractVirtualHosts(
          proto.getRouteConfig(), filterRegistry, args);
      return io.grpc.xds.HttpConnectionManager.forVirtualHosts(
          maxStreamDuration, virtualHosts, filterConfigs);
    }
    if (proto.hasRds()) {
      Rds rds = proto.getRds();
      if (!rds.hasConfigSource()) {
        throw new ResourceInvalidException(
            "HttpConnectionManager contains invalid RDS: missing config_source");
      }
      if (!rds.getConfigSource().hasAds() && !rds.getConfigSource().hasSelf()) {
        throw new ResourceInvalidException(
            "HttpConnectionManager contains invalid RDS: must specify ADS or self ConfigSource");
      }
      return io.grpc.xds.HttpConnectionManager.forRdsName(
          maxStreamDuration, rds.getRouteConfigName(), filterConfigs);
    }
    throw new ResourceInvalidException(
        "HttpConnectionManager neither has inlined route_config nor RDS");
  }

  // hard-coded: currently router config is the only terminal filter.
  private static boolean isTerminalFilter(Filter.FilterConfig filterConfig) {
    return RouterFilter.ROUTER_CONFIG.equals(filterConfig);
  }

  @VisibleForTesting
  @Nullable // Returns null if the filter is optional but not supported.
  static StructOrError<Filter.FilterConfig> parseHttpFilter(
      io.envoyproxy.envoy.extensions.filters.network.http_connection_manager.v3.HttpFilter

View on GitHub (pinned to 64daddc1f3)