Skip to main content
DevOps Insightsguides & answers

Kubernetes · troubleshooting

no matches for kind in version

The cluster does not serve that kind in that apiVersion: the version was removed in a Kubernetes upgrade, or the kind's CRD is not installed. Change the manifest to the served apiVersion, or install the CRD before the resources that use it.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 10 sections

Before you start

  • The manifest or chart that fails, and kubectl access to the cluster.
  • kubectl version, to know which Kubernetes release the cluster runs.

Run this first

step 1 of 2
kubectl api-versions

Look for Whether the apiVersion from your manifest is in the list

Lists every group/version the cluster serves.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Is the kind a built-in one (Ingress, CronJob, Deployment) or an operator's (ServiceMonitor, Certificate)?

Cause space

2 of 2 still possible

  • The manifest uses an apiVersion the cluster no longer servesCommon
  • The kind comes from a CRD that is not installed (yet)Common

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Check it with a tool

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    kubectl api-versions

    Lists every group/version the cluster serves.

    Look for Whether the apiVersion from your manifest is in the list

  2. Step 2

    kubectl api-resources --api-group=GROUP

    Shows the kinds in one group and their served version.

    Look for Your kind and the version to use

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

The manifest uses an apiVersion the cluster no longer serves

Common

The cluster was upgraded past the release that removed that version, or an old chart still ships it.

Confirm

kubectl version
kubectl api-resources | grep -i KIND

The kind listed under a different APIVERSION than the one in your file

Fix

  • Change apiVersion to the served one (for Ingress, networking.k8s.io/v1) and apply the notable field changes from the migration guide.
  • Upgrade the chart to a release that targets your Kubernetes version.
  • For many files, the kubectl-convert plugin rewrites them: kubectl convert -f FILE --output-version GROUP/VERSION. Check the result; it may fill in defaults.
kubectl api-resources | grep -i ingress

Shows the apiVersion the cluster serves for that kind.

The kind comes from a CRD that is not installed (yet)

Common

ServiceMonitor, Certificate, Rollout and similar kinds exist only after their operator's CRDs are installed. Applying them first, or in the same command before the CRD is established, fails.

Confirm

kubectl get crd | grep -i KIND_PLURAL

No CRD for that kind

Fix

  • Install the operator or its CRDs first, then apply the resources that use them.
  • When both are in one apply, wait for the CRD: kubectl wait --for condition=established crd/NAME before applying the custom resources.
  • In Helm, put CRDs in the chart's crds/ directory or install the operator chart before the chart that uses it.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

Every Kubernetes manifest says which version of the API it is written for. Kubernetes retires old versions after a deprecation period, and from then on a cluster refuses manifests that still use them. Kinds added by operators, such as Certificate or ServiceMonitor, only exist once their CustomResourceDefinition is installed. In both cases the cluster has no matching kind to map your file to.

Words used on this page

apiVersion
The API group and version a manifest uses, such as networking.k8s.io/v1. Removed versions are no longer served.
Kind
The type of object, such as Ingress or CronJob.
CRD
CustomResourceDefinition: how operators add their own kinds. Until it is installed, those kinds do not exist.
Served version
A version the API server currently accepts. kubectl api-resources lists them.
What is actually happening

The API server could not map the kind and apiVersion in your manifest to anything it serves. kubectl reports error: resource mapping not found for name: "NAME" namespace: "NS" from "FILE": no matches for kind "KIND" in version "GROUP/VERSION", then ensure CRDs are installed first. Helm wraps the same error in unable to build kubernetes objects from release manifest.

Removed versions, per the Kubernetes migration guide: Deployment, DaemonSet, StatefulSet and ReplicaSet in extensions/v1beta1 and the apps beta versions were removed in 1.16; Ingress in extensions/v1beta1 and networking.k8s.io/v1beta1 in 1.22; CronJob batch/v1beta1, PodDisruptionBudget and PodSecurityPolicy policy/v1beta1 and HorizontalPodAutoscaler autoscaling/v2beta1 in 1.25; autoscaling/v2beta2 in 1.26.

Some replacements are not just a renamed apiVersion. Ingress networking.k8s.io/v1 renamed serviceName and servicePort to service.name and service.port.number or service.port.name, and made pathType required. A policy/v1 PodDisruptionBudget with an empty selector selects all pods, where policy/v1beta1 selected none.

Existing objects are not lost when a version is removed: they remain readable through the new version. The error affects applying old manifests and old charts.

How to tell this is your problem
WhereWhat you see
kubectl applyerror: resource mapping not found for name: "web" namespace: "" from "ingress.yaml": no matches for kind "Ingress" in version "extensions/v1beta1" ensure CRDs are installed first
helm install or upgradeError: unable to build kubernetes objects from release manifest: resource mapping not found for name: … no matches for kind …
TimingRight after a cluster upgrade, or on a fresh cluster before an operator is installed

How to know it is actually fixed

  • kubectl apply --dry-run=server -f FILE succeeds.
  • The chart installs or upgrades without unable to build kubernetes objects.

Stopping it happening again

  • Before a cluster upgrade, check manifests and charts for removed versions; this site's Kubernetes manifest analyzer flags them.
  • Pin chart versions and read their compatibility notes when Kubernetes moves.
  • Install CRDs as a separate, earlier step in deployment pipelines.

Security considerations

  • PodSecurityPolicy was removed in 1.25 with no replacement apiVersion; replace it with Pod Security Admission (or another admission policy), or the protection it gave is simply gone.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it