LearnDevOpsHands-On Labs
Troubleshooting Matrix/no matches for kind "X" in version "Y"
KubernetesHigh Severity

no matches for kind "X" in version "Y"

Fix "no matches for kind in version": run kubectl api-resources, then update the removed apiVersion or install the missing CRD first. Covers Helm and CI order.

Observed Error Signature / Log Pattern
error: unable to recognize "app.yaml": no matches for kind "Ingress" in version "extensions/v1beta1"

Incident Overview

KubernetesKubernetes

Fix "no matches for kind in version": run kubectl api-resources, then update the removed apiVersion or install the missing CRD first. Covers Helm and CI order.

medium fix·6 min read

By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026

BASHDiagnostic / remediation command
error: unable to recognize "app.yaml": no matches for kind "Ingress" in version "extensions/v1beta1"

error: unable to recognize "crd.yaml": no matches for kind "Certificate" in version "cert-manager.io/v1"

error: resource mapping not found for name: "web" namespace: "" from "app.yaml": no matches for kind "CronJob" in version "batch/v1beta1"

Do this first3 steps

Run these in order. Each one tells you what its output means before you change anything.

• Ask the cluster which versions it serves for that kind

The APIVERSION column is the answer. If the kind is listed under a different version than your manifest uses, it is a deprecation. If the kind is absent entirely, the type is not installed.

• If the kind is missing, check whether its CRD exists

No CRD means the controller that defines the type was never installed, or is still starting. Install it before applying anything that uses it.

• Update the manifest to the version the cluster serves

A server-side dry run validates against the live API without changing anything, so you can confirm the fix before applying it for real.

no matches for kind "X" in version "Y" means kubectl asked the API server for a resource type and the server said it does not serve that type at that version. There are only two reasons:

The message is the same for both. One command tells them apart.

BASHDiagnostic / remediation command
kubectl api-resources | grep -i ingress

Ask the cluster what it serves

The kind exists at networking.k8s.io/v1, and your manifest says extensions/v1beta1. That is case 1: a removed API version.

If grep finds nothing, the type is not installed at all. That is case 2.

To see every version of a single kind, including ones being served alongside each other:

BASHDiagnostic / remediation command
kubectl api-resources | grep -i ingress

Case 1: A removed API version

Kubernetes promotes APIs from v1beta1 to v1 and then removes the beta after a deprecation window. Manifests written against the old version stop applying the moment you upgrade the cluster. These are the removals that catch the most people:

Changing apiVersion is often not enough, because the schema usually changed too. Ingress is the clearest example:

pathType is required in v1, and the backend is now a nested object. Editing only the apiVersion line gets you a validation error instead, which at least tells you what is missing.

PodSecurityPolicy is the hard one: it was removed with no replacement resource. You migrate to Pod Security Admission, which is namespace labels rather than an object.

BASHDiagnostic / remediation command
# extensions/v1beta1, no longer served
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: web
              servicePort: 80

Finding these before an upgrade

Do not discover them by upgrading. Check the live cluster for objects on doomed versions:

The API server tracks every deprecated API anyone requests, including the removed_release. That metric is the most reliable pre-upgrade checklist you have, because it reports what is genuinely being used rather than what is in your repository.

For manifests and charts in git, kubectl-convert rewrites them:

It ships separately from kubectl now, so you may have to install it.

BASHDiagnostic / remediation command
kubectl get --raw /metrics 2>/dev/null \
  | grep apiserver_requested_deprecated_apis

Case 2: The CRD is not installed

Nothing returned means the type genuinely does not exist. Certificate, ServiceMonitor, VirtualService, IngressRoute and similar are all defined by controllers you install:

Install the controller first, then your resources.

BASHDiagnostic / remediation command
kubectl get crd | grep cert-manager

The ordering problem in CI and Helm

A single kubectl apply -f ./manifests/ that contains both a CRD and a resource using it can fail even when everything is present, because kubectl builds its type mappings once at the start. The CRD is created during the apply, and the custom resource in the same batch is rejected against the mapping from before it existed.

Apply in two passes:

The kubectl wait matters. A CRD exists before it is Established, and applying against it in that window fails intermittently, which is the sort of flake that only shows up in CI.

Helm has the same problem and solves it with a crds/ directory, which is installed before the templates are rendered. Note that Helm deliberately never upgrades or deletes anything in crds/, so CRD upgrades stay a manual step.

BASHDiagnostic / remediation command
kubectl apply -f manifests/crds/
kubectl wait --for=condition=Established crd/certificates.cert-manager.io --timeout=60s
kubectl apply -f manifests/

A checklist

Frequently Asked Questions

What does "no matches for kind" mean in Kubernetes?

The API server does not serve the resource type at the apiVersion your manifest specifies. Either the kind exists at a different version, which means you are using an API that has been deprecated and removed, or the kind is not installed at all because the CustomResourceDefinition that defines it is missing. kubectl api-resources | grep -i <kind> distinguishes them: if the kind appears with a different APIVERSION it is the first case, and if it does not appear at all it is the second.

Why did my Ingress stop working after upgrading Kubernetes?

extensions/v1beta1 and networking.k8s.io/v1beta1 Ingress were removed in Kubernetes 1.22. The replacement is networking.k8s.io/v1, and the schema changed as well as the version: pathType is now required on every path, and the backend moved from flat serviceName and servicePort fields to a nested service.name and service.port.number. Changing only the apiVersion line produces a validation error rather than a working Ingress, which is at least a clearer message than the original one.

How do I find deprecated APIs before upgrading a cluster?

Read apiserver_requested_deprecated_apis from the API server's metrics endpoint with kubectl get --raw /metrics. Each series names the group, resource, version and the release in which it will be removed, and it reflects what is genuinely being requested against the live cluster rather than what happens to be in your repository. That makes it far more reliable than grepping manifests, because it also catches controllers, operators and Helm charts making calls you never wrote.

Why does kubectl apply fail on a custom resource right after I created its CRD?

kubectl builds its mapping of kinds to API endpoints once, at the start of the command. If the CRD is created during the same apply, the custom resource is validated against the mapping from before that type existed. There is also a window where the CRD object exists but is not yet Established. Apply CRDs as a separate step, then kubectl wait --for=condition=Established crd/<name> before applying the resources that use them. Intermittent failures of this kind are a classic CI flake.

Does Helm handle CRDs differently?

Yes. Files in a chart's crds/ directory are installed before any template is rendered, which solves the ordering problem for a fresh install. The important caveat is that Helm deliberately never upgrades or deletes those CRDs on helm upgrade or helm uninstall, because doing so would delete every custom resource in the cluster along with them. That means CRD upgrades are a manual step you have to plan for, and a chart upgrade that needs a newer CRD schema will fail until you apply it yourself.

Reference and practice

Learn the underlying concept

Other Kubernetes errors

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Get notified about new tutorials and features.

• Roadmaps

• Interview Prep

• Certifications

• Company

© 2026 DevOpsLesson. All rights reserved.

Need to practice this scenario?

Simulate this error condition and practice recovery commands safely in our in-browser terminal.

Open Kubernetes Sandbox