cilium/cilium · error

type URL is required for ADS

Error message

type URL is required for ADS

What it means

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.

Source

Thrown at pkg/envoy/xds/server.go:36

	envoy_service_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
	"google.golang.org/grpc/codes"
	"google.golang.org/protobuf/types/known/anypb"

	"github.com/cilium/cilium/pkg/container/set"
	"github.com/cilium/cilium/pkg/endpointstate"
	"github.com/cilium/cilium/pkg/logging/logfields"
	"github.com/cilium/cilium/pkg/promise"
)

const (
	// AnyTypeURL is the default type URL to use for ADS resource sets.
	AnyTypeURL = ""
)

var (
	// ErrNoADSTypeURL is the error returned when receiving a request without
	// a type URL from an ADS stream.
	ErrNoADSTypeURL = errors.New("type URL is required for ADS")

	// ErrMismatchingTypeURL is the error returned when receiving a request with
	// an unexpected type URL.
	ErrMismatchingTypeURL = errors.New("mismatching type URL")

	// ErrUnknownTypeURL is the error returned when receiving a request with
	// an unknown type URL.
	ErrUnknownTypeURL = errors.New("unknown type URL")

	// ErrInvalidVersionInfo is the error returned when receiving a request
	// with a version info that is not a positive integer.
	ErrInvalidVersionInfo = errors.New("invalid version info")

	// ErrInvalidResponseNonce is returned when a request carries a response
	// nonce that does not match the outstanding response.
	ErrInvalidResponseNonce = errors.New("invalid response nonce info")

	// ErrInvalidNodeFormat is the error returned when receiving a request

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Set TypeUrl on every request, e.g. req.TypeUrl = "type.googleapis.com/envoy.config.listener.v3.Listener".
  2. Upgrade or fix the xDS client so it retains TypeUrl in ACK requests (per the xDS protocol, every request must repeat it).
  3. If using a non-ADS setup, connect to the type-specific xDS endpoints instead of the ADS stream.

Example fix

// before
stream.Send(&discovery.DiscoveryRequest{VersionInfo: version, ResponseNonce: nonce})

// after
stream.Send(&discovery.DiscoveryRequest{VersionInfo: version, ResponseNonce: nonce, TypeUrl: "type.googleapis.com/envoy.config.cluster.v3.Cluster"})
Defensive patterns

Strategy: validation

Validate before calling

const clusterType = "type.googleapis.com/envoy.config.cluster.v3.Cluster"
if req.GetTypeUrl() == "" {
    return status.Error(codes.InvalidArgument, "TypeUrl is required for ADS")
}

Type guard

func hasTypeURL(req *discovery.DiscoveryRequest) bool {
    return req.GetTypeUrl() != ""
}

Try / catch

err := stream.Send(req)
if err != nil && strings.Contains(err.Error(), "type URL is required for ADS") {
    // set req.TypeUrl and resend / fail fast with InvalidArgument
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/12b562dd370f72e0. Report an issue: GitHub.