{"record":{"id":"8e7988922f4fa704","repo":"grpc/grpc-java","slug":"filterchain-filterchainname-contains-filter-l","errorCode":null,"errorMessage":"FilterChain ${filterChainName} contains filter ${l4Filter.getName()} without typed_config","messagePattern":"FilterChain (.+?) contains filter (.+?) without typed_config","errorType":"exception","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsListenerResource.java","lineNumber":243,"sourceCode":"      // null disables FilterChainMatch uniqueness check, used for defaultFilterChain\n      @Nullable Set<FilterChainMatch> filterChainMatchSet,\n      Set<String> certProviderInstances,\n      XdsResourceType.Args args)\n      throws ResourceInvalidException {\n    // FilterChain contains L4 filters, so we ensure it contains only HCM.\n    if (proto.getFiltersCount() != 1) {\n      throw new ResourceInvalidException(\"FilterChain \" + filterChainName\n          + \" should contain exact one HttpConnectionManager filter\");\n    }\n    io.envoyproxy.envoy.config.listener.v3.Filter l4Filter = proto.getFiltersList().get(0);\n    if (!l4Filter.hasTypedConfig()) {\n      throw new ResourceInvalidException(\n          \"FilterChain \" + filterChainName + \" contains filter \" + l4Filter.getName()\n              + \" without typed_config\");\n    }\n    Any any = l4Filter.getTypedConfig();\n    if (!any.getTypeUrl().equals(TYPE_URL_HTTP_CONNECTION_MANAGER)) {\n      throw new ResourceInvalidException(\n          \"FilterChain \" + filterChainName + \" contains filter \" + l4Filter.getName()\n              + \" with unsupported typed_config type \" + any.getTypeUrl());\n    }\n\n    // Parse HCM.\n    HttpConnectionManager hcmProto;\n    try {\n      hcmProto = any.unpack(HttpConnectionManager.class);\n    } catch (InvalidProtocolBufferException e) {\n      throw new ResourceInvalidException(\"FilterChain \" + filterChainName + \" with filter \"\n          + l4Filter.getName() + \" failed to unpack message\", e);\n    }\n    io.grpc.xds.HttpConnectionManager httpConnectionManager = parseHttpConnectionManager(\n        hcmProto, filterRegistry, false /* isForClient */, args);\n\n    // Parse Transport Socket.\n    EnvoyServerProtoData.DownstreamTlsContext downstreamTlsContext = null;\n    if (proto.hasTransportSocket()) {","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsListenerResource.java#L225-L261","documentation":"When the FilterChain's single filter has a typed_config but its type_url is not the expected HttpConnectionManager URL, gRPC rejects it: only HCM is supported as the L4 filter on server-side listeners. The exception includes the filter name and the offending type_url for diagnosis.","triggerScenarios":"A filter's typed_config Any carries a type_url other than type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager - e.g. tcp_proxy, echo, or a custom filter - when parseFilterChain runs.","commonSituations":"Configs ported from Envoy that use tcp_proxy or other network filters; control planes emitting older/renamed HCM type URLs (v2 API vs v3); custom L4 filters not supported by gRPC xDS.","solutions":["Change the filter's typed_config to an HttpConnectionManager v3 message with the correct type_url","If your control plane still emits v2 (envoy.config.filter.network.http_connection_manager.v2) URLs, upgrade it to emit v3 URLs","Remove unsupported network filters from the filter chain; gRPC xDS only accepts HCM"],"exampleFix":"// before\ntype_url: \"type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager\"\n// after\ntype_url: \"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\"","handlingStrategy":"validation","validationCode":"String HCM_URL = \"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\";\nfor (FilterChain fc : listener.getFilterChainsList()) {\n  if (fc.getFiltersCount() == 1\n      && fc.getFilters(0).hasTypedConfig()\n      && !HCM_URL.equals(fc.getFilters(0).getTypedConfig().getTypeUrl())) {\n    throw new IllegalArgumentException(\"Only HCM v3 filters are supported, got \"\n        + fc.getFilters(0).getTypedConfig().getTypeUrl());\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  listener = XdsListenerResource.parseServerSideListener(proto, ...);\n} catch (ResourceInvalidException e) {\n  if (e.getMessage().contains(\"unsupported typed_config type\")) {\n    logger.warn(\"Replace non-HCM filter with HttpConnectionManager v3\", e);\n  }\n}","preventionTips":["Pin control-plane output to v3 Envoy API type URLs","Strip non-HCM network filters when targeting gRPC xDS","Add a type_url allowlist check in control-plane CI"],"tags":["xds","grpc","filter-chain","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}