{"record":{"id":"12b562dd370f72e0","repo":"cilium/cilium","slug":"type-url-is-required-for-ads","errorCode":null,"errorMessage":"type URL is required for ADS","messagePattern":"type URL is required for ADS","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/envoy/xds/server.go","lineNumber":36,"sourceCode":"\tenvoy_service_discovery \"github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/cilium/cilium/pkg/container/set\"\n\t\"github.com/cilium/cilium/pkg/endpointstate\"\n\t\"github.com/cilium/cilium/pkg/logging/logfields\"\n\t\"github.com/cilium/cilium/pkg/promise\"\n)\n\nconst (\n\t// AnyTypeURL is the default type URL to use for ADS resource sets.\n\tAnyTypeURL = \"\"\n)\n\nvar (\n\t// ErrNoADSTypeURL is the error returned when receiving a request without\n\t// a type URL from an ADS stream.\n\tErrNoADSTypeURL = errors.New(\"type URL is required for ADS\")\n\n\t// ErrMismatchingTypeURL is the error returned when receiving a request with\n\t// an unexpected type URL.\n\tErrMismatchingTypeURL = errors.New(\"mismatching type URL\")\n\n\t// ErrUnknownTypeURL is the error returned when receiving a request with\n\t// an unknown type URL.\n\tErrUnknownTypeURL = errors.New(\"unknown type URL\")\n\n\t// ErrInvalidVersionInfo is the error returned when receiving a request\n\t// with a version info that is not a positive integer.\n\tErrInvalidVersionInfo = errors.New(\"invalid version info\")\n\n\t// ErrInvalidResponseNonce is returned when a request carries a response\n\t// nonce that does not match the outstanding response.\n\tErrInvalidResponseNonce = errors.New(\"invalid response nonce info\")\n\n\t// ErrInvalidNodeFormat is the error returned when receiving a request","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/envoy/xds/server.go#L18-L54","documentation":"ErrNoADSTypeURL is the sentinel error returned when a request arrives on an ADS (Aggregated Discovery Service) stream without a type URL. In ADS, all resource types are multiplexed over one gRPC stream, so each DiscoveryRequest must carry a TypeUrl to identify which resource (listeners, clusters, routes, endpoints, etc.) it concerns. An empty TypeUrl (equal to the AnyTypeURL constant \"\") makes the request unprocessable.","triggerScenarios":"processRequestStream or processDeltaRequestStream receives a DiscoveryRequest / DeltaDiscoveryRequest on an ADS stream whose TypeUrl is the empty string, including follow-up ACK requests that drop the TypeUrl.","commonSituations":"A misbehaving or old xDS client omits TypeUrl in its initial request or in ACK/NACK follow-ups; hand-written test clients forget to set TypeUrl; a client written for non-ADS (separate-stream) xDS assumes TypeUrl is optional.","solutions":["Set TypeUrl on every request, e.g. req.TypeUrl = \"type.googleapis.com/envoy.config.listener.v3.Listener\".","Upgrade or fix the xDS client so it retains TypeUrl in ACK requests (per the xDS protocol, every request must repeat it).","If using a non-ADS setup, connect to the type-specific xDS endpoints instead of the ADS stream."],"exampleFix":"// before\nstream.Send(&discovery.DiscoveryRequest{VersionInfo: version, ResponseNonce: nonce})\n\n// after\nstream.Send(&discovery.DiscoveryRequest{VersionInfo: version, ResponseNonce: nonce, TypeUrl: \"type.googleapis.com/envoy.config.cluster.v3.Cluster\"})","handlingStrategy":"validation","validationCode":"const clusterType = \"type.googleapis.com/envoy.config.cluster.v3.Cluster\"\nif req.GetTypeUrl() == \"\" {\n    return status.Error(codes.InvalidArgument, \"TypeUrl is required for ADS\")\n}","typeGuard":"func hasTypeURL(req *discovery.DiscoveryRequest) bool {\n    return req.GetTypeUrl() != \"\"\n}","tryCatchPattern":"err := stream.Send(req)\nif err != nil && strings.Contains(err.Error(), \"type URL is required for ADS\") {\n    // set req.TypeUrl and resend / fail fast with InvalidArgument\n}","preventionTips":["Every ADS request must repeat its TypeUrl — including ACKs and NACKs.","Centralize type URL constants instead of hand-typing strings.","Unit-test that your client's ACK path preserves TypeUrl.","If you don't need aggregation, use type-specific xDS streams where TypeUrl is implicit."],"tags":["envoy","xds","ads","grpc"],"backgroundTag":"missing-required-field","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}