grpc/grpc-go · error

no ResourceType implementation found for typeURL %q

Error message

no ResourceType implementation found for typeURL %q

What it means

Reported to the watcher (and logged as a Warning) by XDSClient.WatchResource when the requested typeURL is not a key in Config.ResourceTypes. The watch never starts; WatchResource returns a no-op cancel function and the watcher receives a ResourceError callback. (Note: the log line prints rType.TypeURL which is empty because the lookup failed; the real typeURL is the one the caller passed.)

Source

Thrown at internal/xds/clients/xdsclient/clientimpl_watchers.go:69

// The returned function cancels the watch and prevents future calls to the
// watcher.
func (c *XDSClient) WatchResource(typeURL, resourceName string, watcher ResourceWatcher) (cancel func()) {
	// Return early if the client is already closed.
	if c.done.HasFired() {
		logger.Warningf("Watch registered for type %q, but client is closed", typeURL)
		return func() {}
	}

	watcher = &wrappingWatcher{
		ResourceWatcher: watcher,
		nodeID:          c.config.Node.ID,
	}

	rType, ok := c.config.ResourceTypes[typeURL]
	if !ok {
		logger.Warningf("ResourceType implementation for resource type url %q is not found", rType.TypeURL)
		c.serializer.TrySchedule(func(context.Context) {
			watcher.ResourceError(fmt.Errorf("no ResourceType implementation found for typeURL %q", rType.TypeURL), func() {})
		})
		return func() {}
	}

	n := xdsresource.ParseName(resourceName)
	a := c.getAuthorityForResource(n)
	if a == nil {
		logger.Warningf("Watch registered for name %q of type %q, authority %q is not found", rType.TypeName, resourceName, n.Authority)
		c.serializer.TrySchedule(func(context.Context) {
			watcher.ResourceError(fmt.Errorf("authority %q not found in the config for resource %q", n.Authority, resourceName), func() {})
		})
		return func() {}
	}
	// The watchResource method on the authority is invoked with n.String()
	// instead of resourceName because n.String() canonicalizes the given name.
	// So, two resource names which don't differ in the query string, but only
	// differ in the order of context params will result in the same resource
	// being watched by the authority.

View on GitHub (pinned to 03255a9237)

Solutions

  1. Register a ResourceType implementation for the typeURL in Config.ResourceTypes before constructing XDSClient.
  2. Compare the typeURL passed to WatchResource against the TypeURL field of your ResourceType (watch for trailing slashes, scheme mismatches, v2 vs v3).
  3. Use the well-known constant URLs (e.g. the ones exported by the resource packages) rather than hand-typing strings.

Example fix

// before: typeURL not in ResourceTypes
cfg := xdsclient.Config{ ResourceTypes: map[string]ResourceType{} }
c, _ := xdsclient.New(cfg)
c.WatchResource("type.googleapis.com/envoy.config.listener.v3.Listener", "foo", w) // -> error

// after: register the resource type
cfg := xdsclient.Config{
  ResourceTypes: map[string]ResourceType{ listenerType.TypeURL: listenerType },
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every typeURL you will watch is registered before building the client.
func validateTypeURLs(cfg xdsclient.Config, want []string) error {
    for _, u := range want {
        if _, ok := cfg.ResourceTypes[u]; !ok {
            return fmt.Errorf("ResourceType not registered for %q", u)
        }
    }
    return nil
}

Type guard

func isRegisteredTypeURL(cfg xdsclient.Config, typeURL string) bool {
    _, ok := cfg.ResourceTypes[typeURL]
    return ok
}

Prevention

When it happens

Trigger: Calling WatchResource with a typeURL string that was not registered in the ResourceTypes map of the Config passed to xdsclient.New — e.g. an LDS/RDS/CDS/EDS URL that no ResourceType implementation was provided for, or a typo in the typeURL.

Common situations: Building an XDSClient with a partial ResourceTypes map (only some of the standard types registered), passing a URL with the wrong scheme/host, or version skew where the registered TypeURL differs from what the caller requests.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/678c429ce0ddeec5. Report an issue: GitHub.