A deprecated Kubernetes API keeps working normally for an announced period, generally at least a year or three minor versions for a stable (v1) API, before being permanently removed. A manifest referencing an already-removed apiVersion doesn’t degrade gradually: kubectl apply fails immediately with an explicit error, often at the worst possible moment, during a cluster version upgrade planned weeks in advance.

The real deprecation pace

Kubernetes guarantees a stable (v1) API stays available at least 12 months or 3 minor versions after its deprecation is officially announced, whichever is longer. A beta-version API gets a shorter guarantee (9 months or 3 minor versions). This policy gives a real migration window, but only if you follow deprecation announcements, not once the API is already gone.

# The error message at the moment of actual removal,
# never a gradual warning beforehand
kubectl apply -f old-manifest.yaml
# error: resource mapping not found for name: "my-ingress"
# no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

Removals that already happened, not just theoretical

extensions/v1beta1 and apps/v1beta1 disappeared in 1.16; networking.k8s.io/v1beta1 for Ingress in 1.22; policy/v1beta1 for PodSecurityPolicy in 1.25 (removed along with the feature itself, replaced by Pod Security Standards). Every major cluster version upgrade is the real moment where old manifests, written years earlier and never revisited, abruptly stop working.

Detecting before the upgrade, not during

pluto, a tool dedicated to this detection, scans a manifest repository or a running cluster to spot any apiVersion deprecated or already removed in the target version.

# Detects deprecated apiVersions before the upgrade,
# not at the moment apply fails mid-version-bump
pluto detect-files -d ./manifests

Running this detection before any version upgrade planning turns a last-minute failure into an anticipated fix, a step as routine as checking the version changelog’s breaking changes, but far more often forgotten.

Converting rather than rewriting by hand

kubectl convert (a separate plugin, installed independently) automatically translates a manifest written in an old apiVersion to its equivalent in the target version, when the structure allows it.

# Automatic conversion to the new apiVersion,
# rather than a manual field-by-field rewrite
kubectl convert -f old-manifest.yaml --output-version apps/v1

This automatic conversion doesn’t cover every case: some API version changes alter a field’s structure or default behavior, which requires manual review even after conversion, not blind trust in the tool.

Takeaway

A deprecated Kubernetes API stays guaranteed functional for an announced duration (12 months or 3 minor versions for a stable API), but its actual removal immediately breaks any manifest still referencing it, with no prior gradual degradation. pluto detects these dependencies before a planned version upgrade, rather than discovering the problem when apply fails; kubectl convert automates part of the migration, without exempting a manual review. Systematically checking the apiVersions in use before any major version upgrade is one of the habits separating a planned Kubernetes migration from an upgrade that breaks production with no warning.