Fix Kubernetes Error: no matches for kind "Ingress" in version "extensions/v1beta1"

intermediate☸️ Kubernetes2026-07-10| Kubernetes 1.22+, kubectl CLI, Linux / macOS / Windows

Error Message

error: unable to recognize "deploy.yaml": no matches for kind "Ingress" in version "extensions/v1beta1"
#kubernetes#api-version#deprecated#ingress#migration

The Error

error: unable to recognize "deploy.yaml": no matches for kind "Ingress" in version "extensions/v1beta1"

You ran kubectl apply -f against a Kubernetes 1.22+ cluster and it blew up β€” even though the YAML looks perfectly fine. The problem isn't your syntax. It's that the API version in that file no longer exists on the cluster.

Root Cause

Kubernetes 1.22 deleted the extensions/v1beta1 API group entirely. Not deprecated β€” deleted. The API server has no record of what an Ingress under that group means, which is exactly what "no matches for kind" is telling you.

The Ingress API went through three generations before this happened:

  • ≀ 1.13: Only extensions/v1beta1 available
  • 1.14: networking.k8s.io/v1beta1 introduced; extensions/v1beta1 marked deprecated
  • 1.19: networking.k8s.io/v1 promoted to stable
  • 1.22: Both beta versions axed β€” this is when the error starts appearing

Worth noting: Deployment, DaemonSet, and ReplicaSet under extensions/v1beta1 were already cut in 1.16. Multiple resource types failing at once usually means your manifests originate from Kubernetes 1.14 or earlier.

Fix: Update the Manifest

Changing the apiVersion line alone won't cut it. The networking.k8s.io/v1 Ingress spec restructured the backend field and made pathType required. Three things need to change.

Old (extensions/v1beta1 β€” broken on 1.22+)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80

New (networking.k8s.io/v1 β€” works on 1.19+)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

Here's exactly what moved:

  • backend.serviceName β†’ backend.service.name
  • backend.servicePort β†’ backend.service.port.number (or .name for named ports)
  • pathType is now required β€” use Prefix, Exact, or ImplementationSpecific

Bulk Migration with kubectl-convert

Got dozens of manifests to update? The kubectl-convert plugin handles the conversion automatically instead of forcing you to edit each file by hand:

# Install the plugin (Linux)
curl -LO "https://dl.k8s.io/release/$(kubectl version --client -o json | jq -r .clientVersion.gitVersion)/bin/linux/amd64/kubectl-convert"
chmod +x kubectl-convert
sudo mv kubectl-convert /usr/local/bin/

# Preview the converted output
kubectl convert -f old-ingress.yaml --output-version networking.k8s.io/v1

# Save to a new file
kubectl convert -f old-ingress.yaml --output-version networking.k8s.io/v1 > new-ingress.yaml

Before a cluster upgrade, run pluto to scan your entire repository for deprecated API usage in one shot:

# Install pluto (macOS)
brew install FairwindsOps/tap/pluto

# Scan all YAML files in a directory
pluto detect-files -d ./k8s/

# Check what's currently running in the live cluster
pluto detect-all-in-cluster

Verify the Fix

First, confirm your cluster actually exposes the target API:

kubectl api-versions | grep networking
# Should include: networking.k8s.io/v1

Apply the updated manifest and inspect the result:

kubectl apply -f deploy.yaml
# Expected output: ingress.networking.k8s.io/my-ingress created

kubectl get ingress my-ingress
kubectl describe ingress my-ingress

One catch: if this Ingress was previously deployed under the old API, the cluster may still hold the stale object. Delete it first, then re-apply:

kubectl delete ingress my-ingress
kubectl apply -f deploy.yaml

Prevention

  • Add pluto detect-files -d ./k8s/ to your CI pipeline β€” it flags deprecated API versions before they ever touch a cluster.
  • Before upgrading, read the Kubernetes API deprecation guide for the target version. Every removal is listed there explicitly.
  • When editing YAML by hand, paste it into ToolCraft's YAML ↔ JSON Converter to catch structural problems early. It runs entirely in the browser β€” nothing leaves your machine β€” which matters when manifests contain cluster credentials or internal hostnames.
  • On any unfamiliar cluster, run kubectl api-resources | grep ingress before deploying so you know exactly what's available.

Related Error Notes