{"record":{"id":"116711898bd983fc","repo":"grpc/grpc-java","slug":"unsupported-clusterspecifierplugin-type-typeurl","errorCode":null,"errorMessage":"Unsupported ClusterSpecifierPlugin type: ${typeUrl}","messagePattern":"Unsupported ClusterSpecifierPlugin type: (.+?)","errorType":"exception","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java","lineNumber":632,"sourceCode":"    String pluginName = extension.getName();\n    Any anyConfig = extension.getTypedConfig();\n    String typeUrl = anyConfig.getTypeUrl();\n    Message rawConfig = anyConfig;\n    if (typeUrl.equals(TYPE_URL_TYPED_STRUCT_UDPA) || typeUrl.equals(TYPE_URL_TYPED_STRUCT)) {\n      try {\n        TypedStruct typedStruct = unpackCompatibleType(\n            anyConfig, TypedStruct.class, TYPE_URL_TYPED_STRUCT_UDPA, TYPE_URL_TYPED_STRUCT);\n        typeUrl = typedStruct.getTypeUrl();\n        rawConfig = typedStruct.getValue();\n      } catch (InvalidProtocolBufferException e) {\n        throw new ResourceInvalidException(\n            \"ClusterSpecifierPlugin [\" + pluginName + \"] contains invalid proto\", e);\n      }\n    }\n    io.grpc.xds.ClusterSpecifierPlugin plugin = registry.get(typeUrl);\n    if (plugin == null) {\n      if (!pluginProto.getIsOptional()) {\n        throw new ResourceInvalidException(\"Unsupported ClusterSpecifierPlugin type: \" + typeUrl);\n      }\n      return null;\n    }\n    ConfigOrError<? extends PluginConfig> pluginConfigOrError = plugin.parsePlugin(rawConfig);\n    if (pluginConfigOrError.errorDetail != null) {\n      throw new ResourceInvalidException(pluginConfigOrError.errorDetail);\n    }\n    return pluginConfigOrError.config;\n  }\n\n  static final class RdsUpdate implements ResourceUpdate {\n    // The list virtual hosts that make up the route table.\n    final List<VirtualHost> virtualHosts;\n\n    RdsUpdate(List<VirtualHost> virtualHosts) {\n      this.virtualHosts = Collections.unmodifiableList(\n          new ArrayList<>(checkNotNull(virtualHosts, \"virtualHosts\")));\n    }","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsRouteConfigureResource.java#L614-L650","documentation":"The ClusterSpecifierPlugin's type_url does not correspond to any plugin implementation registered in the ClusterSpecifierPlugin registry. Unless the plugin is marked is_optional, the RouteConfiguration is rejected because gRPC cannot interpret the plugin semantics.","triggerScenarios":"parseClusterSpecifierPlugin: registry.get(typeUrl) returns null (unknown type_url in the plugin's extension config) and pluginProto.getIsOptional() is false.","commonSituations":"Configs authored for newer/other Envoy plugin types (e.g. matcher-based plugins not yet supported by the gRPC version); version skew between control plane and grpc-xds; typo'd type_url in hand-written configs.","solutions":["Upgrade grpc-xds to a version that supports the plugin type referenced by the type_url","Change the route config to use a supported cluster specifier (plain cluster or weighted clusters)","If the plugin is genuinely optional, set is_optional: true on the ClusterSpecifierPlugin so it's skipped","Fix a typo'd or wrong type_url in the plugin extension config"],"exampleFix":"// before\ncluster_specifier_plugins: [{\n  extension: {name: \"p\", typed_config: {\"@type\": \"type.googleapis.com/unknown.Plugin\"}}\n}]\n// after\ncluster_specifier_plugins: [{\n  extension: {name: \"p\", typed_config: {\"@type\": \"type.googleapis.com/xds.type.matcher.v3.Matcher\", ...}},\n  is_optional: true\n}]","handlingStrategy":"fallback","validationCode":"// Check plugin type support before deploying the route config\nString typeUrl = extractTypeUrl(plugin.getTypedConfig());\nif (!SUPPORTED_PLUGIN_TYPE_URLS.contains(typeUrl) && !plugin.getIsOptional()) {\n  throw new IllegalArgumentException(\"Unsupported plugin type: \" + typeUrl);\n}","typeGuard":null,"tryCatchPattern":"try {\n  xdsClient.watchResource(ROUTE_CONFIGURATION, name, watcher);\n} catch (ResourceInvalidException e) {\n  if (e.getMessage().startsWith(\"Unsupported ClusterSpecifierPlugin type\")) {\n    log.warn(\"Falling back to non-plugin routing\");\n  }\n}","preventionTips":["Upgrade grpc-xds when the control plane emits newer plugin types","Mark non-critical plugins is_optional so unsupported types are skipped","Keep an allowlist of plugin type_urls supported by your gRPC version"],"tags":["xds","grpc","unsupported-feature","version-skew"],"backgroundTag":"unsupported-config-value","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}