GoogleContainerTools/skaffold · error

listing resources of kind %v: %w

Error message

listing resources of kind %v: %w

What it means

CustomResourceSelector.Select resolves the GroupVersionResource for the configured custom resource kind via discovery. If discovery lookup of the kind fails (kind not registered on the cluster/API server), the error is wrapped as `listing resources of kind <kind>: ...`. It means skaffold cannot map the kind to a REST resource before even listing.

Source

Thrown at pkg/diag/validator/custom_resource.go:74

		rs = append(rs, NewResourceFromObject(&r, Status(status), ae, nil))
	}
	return rs, nil
}

// NewCustomValidator initializes a CustomValidator
func NewCustomValidator(k kubernetes.Interface, d dynamic.Interface, gvk schema.GroupVersionKind) *CustomValidator {
	return &CustomValidator{resourceSelector: NewCustomResourceSelector(k, d, gvk)}
}

func NewCustomResourceSelector(client kubernetes.Interface, dynClient dynamic.Interface, gvk schema.GroupVersionKind) *CustomResourceSelector {
	return &CustomResourceSelector{client: client, dynClient: dynClient, kind: gvk}
}

// Select returns the updated list of custom resources for the given GroupVersionKind deployed by skaffold
func (c *CustomResourceSelector) Select(ctx context.Context, namespace string, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
	_, r, err := util.GroupVersionResource(c.client.Discovery(), c.kind)
	if err != nil {
		return nil, fmt.Errorf("listing resources of kind %v: %w", c.kind, err)
	}
	resList, err := c.dynClient.Resource(r).Namespace(namespace).List(ctx, opts)
	if err != nil {
		return nil, fmt.Errorf("listing resources of kind %v: %w", c.kind, err)
	}
	return resList, nil
}

func getResourceStatus(res unstructured.Unstructured) (kstatus.Status, *proto.ActionableErr) {
	result, err := kstatus.Compute(&res)
	if err != nil || result == nil {
		return kstatus.UnknownStatus, &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: "unable to check resource status"}
	}
	var ae proto.ActionableErr
	switch result.Status {
	case kstatus.CurrentStatus:
		ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS}
	case kstatus.InProgressStatus:

View on GitHub (pinned to a1189de023)

Solutions

  1. Apply the CRD to the cluster: `kubectl apply -f <crd.yaml>` and verify with `kubectl api-resources | grep <kind>`.
  2. Fix the kind/apiGroup name in your skaffold config to match the installed CRD exactly.
  3. Confirm you are pointed at the intended cluster (`kubectl config current-context`).

Example fix

// before (kind not installed)
skaffold diagnose  # listing resources of kind MyKind: the server could not find...
// after
kubectl apply -f crds/mykind-crd.yaml && skaffold diagnose
Defensive patterns

Strategy: validation

Validate before calling

out, _ := exec.Command("kubectl", "api-resources").Output()
if !strings.Contains(string(out), kind) {
    return fmt.Errorf("kind %s not installed in cluster; apply its CRD first", kind)
}

Try / catch

if err := selector.Select(ctx, ns, opts); err != nil {
    if strings.Contains(err.Error(), "listing resources of kind") {
        // verify CRD is applied / kind spelling
    }
}

Prevention

When it happens

Trigger: Calling Select (via Validate/diagnose) for a CRD kind that is not installed in the target cluster — discovery returns no match for util.GroupVersionResource; also fires on discovery API connectivity errors.

Common situations: Diagnosing a cluster where the CRD (e.g. some custom workload kind) hasn't been applied yet; wrong apiGroup/kind spelling in config; connecting skaffold to the wrong kubeconfig context.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/ba0be0ae77d7abd8. Report an issue: GitHub.