Why Kubernetes deprecated API migration comes before every cluster upgrade
A team whose manifests, Helm charts or operators still call an API that the target Kubernetes release removes must find and fix those objects before kube-apiserver moves to that release. The API server rejects requests for a removed API version, so a workload applied years ago can fail on its next update, and a controller that watches the old version can stop reconciling without an obvious error. This is the step that most often blocks an upgrade, and it costs little to do early. Treat the migration as a gate in the change plan, completed before the control plane is touched.
The supported release path explains why this work cannot wait. The Kubernetes project maintains the three most recent minor releases, and as of September 2026 those were 1.37, 1.36 and 1.35. Their end-of-life dates are October 28, 2027 for 1.37, June 28, 2027 for 1.36 and February 28, 2027 for 1.35. A cluster that stays on an older minor loses patch support, so the team cannot postpone the decision indefinitely. Confirm the current list on the Kubernetes releases page before you set a date, because the window moves as new releases ship.
Releases arrive about three times a year on a cycle of roughly 14 weeks, so a team that skips a version falls behind quickly. The version skew policy requires kube-apiserver to be upgraded one minor version at a time, and the other control plane components and kubelets follow under their own skew limits. Each step therefore repeats the deprecation check for the next target as well as the final one. A cluster moving from 1.35 to 1.37 needs its objects checked for what the intermediate release removes, as well as for 1.37. Read the deprecation guide for each target version in order and record what changed.
Start with an inventory. List every API group and version in use across your Git repositories, rendered Helm releases and running clusters, including custom resources managed by operators and any admission webhooks that might submit old versions. Tools such as kubectl convert can rewrite a manifest to a newer API version, but the output needs review because the schema can change between versions. Ask your platform team who owns each Helm chart and operator, and whether their current releases support the target version. Those owners often hold the fix, and a chart upgrade may be the only change needed.
Plan for the findings before the change window opens. Decide who approves changes to charts and operators, how each fix will be tested against a staging cluster running the target version, and what happens to workloads that cannot be migrated in time. If you bring in a partner, ask which checks they run, how they report objects that still use removed APIs, and how they keep the inventory current after the upgrade. Confirm each removal against the release notes for your target version, since the list is specific to each release.
What changes between Kubernetes minor releases that affects workloads
This table compares the kinds of change that affect workloads between Kubernetes minor releases, with the impact of each and the action to take before upgrading. Read each row against the target version's release notes and deprecation guide, which list the exact removed APIs. The main takeaway is that removed APIs usually break workloads only after the upgrade, so inventory manifests, charts and operators first.
| Change | Impact | Action needed |
|---|---|---|
| APIs removed in the target release | Resources using them are rejected or fail to apply once the cluster serves the new release. | Check the target version's release notes and deprecation guide for the removed list, then search manifests for those versions. |
| Deprecated APIs that still work | Served in the target release but scheduled for removal, so they become upgrade blockers later. | Move to the replacement version now. Use kubectl convert where it supports the change. |
| Operator and CRD version bundles | Operators and their CRDs may serve only API versions the target release supports, and older operator builds may not run on it. | Confirm the operator's compatibility with the target minor, then upgrade operators and CRDs in the order the vendor documents. |
| Helm chart templates pinned to old API versions | Charts that render removed apiVersions fail on helm upgrade even when running workloads still work. | Render each chart against the target version, fix templates, then release updated chart versions. |
| Control plane and kubelet skew | kube-apiserver must move one minor version at a time, and kubelets may run up to three minor versions behind it. | Upgrade kube-apiserver first, then controller-manager and scheduler, then kubelets. Confirm your path with the skew policy. |
| End-of-life dates of current minor releases | As of September 2026: 1.35 ends February 28, 2027, 1.36 June 28, 2027, and 1.37 October 28, 2027. | Set target versions against these dates and confirm current dates on the Kubernetes releases page before planning. |
How to find deprecated API usage in manifests, charts and operators
Build the inventory of deprecated API usage in a fixed order, and finish it before you choose an upgrade path. Start with the deprecation guide and the release notes for each target minor version, since these name the APIs being removed, the version where each removal takes effect, and the replacement API. Take the target versions from your upgrade plan and confirm them on kubernetes.io/releases. Kubernetes maintains only the three most recent minor releases, so a cluster several minors behind may cross more removals than the single step you planned for. Record each removed API in a working list with its target version and the replacement group and version, so every later scan checks against the same list.
Next, run kubectl convert against exported manifests where your kubectl version supports it. Export from Git first, and render Helm charts with helm template so you scan the output the cluster would receive, not the template source. Before relying on the command, confirm in your own environment that kubectl convert is available, check its flags with the help output for your kubectl version, and test it on a sample file you already know uses an old API. Treat its output as a strong signal, not a complete answer. It can only convert manifests it understands, so files it skips or rejects still need a manual review against your working list.
Then check what is running, not only what is stored in Git. Query the API server for live objects of each removed kind across all namespaces, and compare the results with the repository. Manifests applied by hand, by a controller or by a pipeline that has since changed can drift from the Git history. For Helm, list releases in every namespace, read the stored manifest for each release, and map each release back to a chart version and a Git path. Releases with no chart in Git are the highest risk, because nobody can change their templates before the upgrade. Confirm with your Helm version where release records are stored, and whether your control plane exposes any signal, such as audit events or metrics, that shows requests to deprecated APIs.
Finish with operators and custom resource definitions. Each operator and CRD bundles the API versions it serves and may depend on removed APIs internally. Review the CRD versions served and stored, any conversion webhooks, and the operator release notes for compatibility with your target minor version. Decide per operator whether to upgrade it before or after the Kubernetes step, and confirm that order with the vendor. Keep one findings register with the resource, namespace, owner, target version, fix and verification status for each item, and repeat the scan at every minor step, since the version skew policy requires control plane components to move one minor version at a time.
What to back up and inventory before changing any API version
Each item below produces a record or copy that the migration depends on. Complete them in order, since the inventory needs a consistent Git state and the staging test needs images you can pull.
etcd snapshot and tested restore
Take an etcd snapshot with etcdctl snapshot save before any API version change, and store it outside the control plane nodes. Then rehearse a restore with etcdutl on a scratch cluster, because a snapshot that has never been restored is unverified. The platform owner signs off on the snapshot location, retention period and restore runbook. The security lead should confirm the snapshots are encrypted, since Secrets are stored unencrypted in etcd by default unless encryption at rest is configured.
Helm release, operator and CRD inventory
List every Helm release with its chart version, every operator with its installed version, and every custom resource definition in the cluster. For each one, record the API versions it serves and the versions its manifests reference, since a chart can look current while its templates still render removed APIs. Operators and CRDs often need their own upgrade before the target release, so ask each application owner to confirm the minimum versions they support. Application owners sign off on their entries.
Manifest repository and GitOps state
Confirm that the manifest repository matches what runs in the cluster before you scan it. Drift between Git and live objects hides deprecated APIs, and a GitOps controller can reapply an old manifest after you fix it. Record the branch, tag or commit each sync target uses, and pause automated sync for affected applications during the migration window. The platform team signs off, with a named reviewer for each repository.
Staging cluster on matching minor versions
Run a staging cluster on the same minor version as production, with the same add-ons, CRDs and admission policies, so the migration test reflects production behavior. The version skew policy requires kube-apiserver to move one minor version at a time, so staging should follow the same upgrade path planned for production. Include representative workloads from the inventory. The release manager signs off that staging matches production in version and configuration.
Private registry mirrors for offline clusters
For clusters without internet access, list the control plane images with kubeadm config images list, pull them with kubeadm config images pull, and push them to a private registry. Point kubeadm init at that registry with --image-repository, and confirm the matching option for upgrade commands in the kubeadm documentation. Include the add-on and operator images that the migrated manifests reference. The infrastructure owner signs off on the mirror contents and the registry's access controls.
Why the upgrade path must step through each minor version
The upgrade path for a self-managed cluster has to pass through every minor version between the current release and the target, and the reason is the Kubernetes version skew policy. That policy requires kube-apiserver to be upgraded one minor version at a time, and to be upgraded before kube-controller-manager, kube-scheduler and kubelets. Kubelets may run up to three minor versions behind the API server, so a node pool can lag behind the control plane for a while, but the control plane itself cannot jump. For the operator, this turns deprecated API cleanup into a sequence problem: the order in which API fixes are made has to follow the order in which the control plane will move.
Because each control plane step is one minor version, every manifest, Helm chart and operator that depends on an API has to work on each intermediate target, not only on the final one. A workload that is corrected for the release you are upgrading to may still break on an earlier intermediate release if it uses an API that is removed there. The practical check is to build a table with one row per intermediate target, listing the APIs that are removed or deprecated in that release, and then assign each workload fix to the step where it first becomes necessary. Confirm the removal list for each release in that release's own notes, not from memory or from a summary of a later release.
Intermediate releases can remove APIs in their own right, so the removal list is not simply the difference between your starting and final versions. An API that was deprecated long ago may be removed on a middle step, and a cluster that only checks the final target can pass that check and still fail during the upgrade. Plan for this by asking your platform team and any chart or operator vendors which intermediate releases they have tested, and by reviewing the release notes for every minor version in the path. Record the outcome of each review so that an auditor or a later operator can see why each step was approved.
The version skew policy also sets limits on how long mixed-version states can last. Kubelets can lag the API server by up to three minor versions, but that allowance does not mean the lag should be used as a buffer. Each step still needs its own API check, its own workload validation and a rollback point, and the team should decide in advance how many minor versions they will allow kubelets to trail during the upgrade window. Confirm with your distribution vendor whether it supports the same skew allowance, because a packaged distribution may set its own upgrade rules on top of the upstream policy.
How to run the API migration and upgrade in order, with checks and rollback points
This sequence moves a self-managed cluster through each target minor version only after its deprecated API usage is found, fixed and tested. Each step names the check that passes it and the last point where rolling back stays clean, so the team knows when it can stop and when it must restore from a verified etcd snapshot.
Confirm the target version and path
Record the kube-apiserver and kubelet versions on every node, then choose the target from the minor releases the project still maintains on the Kubernetes releases page. The version skew policy requires kube-apiserver to move one minor version at a time, so an illustrative cluster on 1.35 would pass through 1.36 before reaching 1.37. Confirm that your CNI plugin, storage driver, ingress controller and Helm charts publish support for each version on that path. Rollback is still clean here because nothing in the cluster has changed. The output is a written upgrade path with one version per stage and a named owner for each stage.
Inventory and fix deprecated API usage
Scan manifests in Git, live cluster objects, Helm releases and operator-installed custom resources for APIs removed in the target release. Use the Kubernetes deprecation guide to map each old API version to its replacement. Use kubectl convert where it fits, then review the converted output against the target schema, because automated conversion can miss fields whose meaning has changed. Apply fixes to the sources in Git so the next deploy does not bring the old API back. The step passes when a fresh scan finds no removed APIs in use, or every remaining item has an owner and a documented fix. Rollback is clean because the changes sit in version control and can be reverted.
Validate fixes in a staging cluster
Apply the fixed manifests and Helm releases to a staging cluster that matches production as closely as your environment allows, starting at the current version. Run server-side dry runs against the target API server where your tooling supports them, then deploy and run your application smoke tests and operator health checks. If a staging copy of the target version is available, run the full set of changes there as well. The step passes when every workload reaches its ready state, the staging scan is clean and smoke tests succeed. Production has not changed at this point, so stopping here is a clean rollback.
Take and verify an etcd snapshot
Take a snapshot of etcd with etcdctl snapshot save from a healthy member, then check the file with the status command in the etcd tooling your version ships. Copy the snapshot off the control plane nodes to storage that survives the upgrade. Confirm that all etcd members are healthy before you start, because an unhealthy member can complicate both the upgrade and any restore. For stacked control planes, record which nodes hold etcd members. Where your team has not rehearsed a restore, do that on a separate host using etcdutl before the upgrade begins. The step passes when the snapshot is readable, stored off-cluster and the restore has been rehearsed. This snapshot is the restore point for everything that follows.
Upgrade control plane nodes with kubeadm
On the first control plane node, run kubeadm upgrade plan to confirm the available target, then kubeadm upgrade apply with that version. Upgrade the kubelet and kubectl packages from the package repository for the target minor version, and restart the kubelet. On each remaining control plane node, run kubeadm upgrade node and repeat the package step. Keep the load balancer in front of kube-apiserver on port 6443 in view throughout, because it must route only to healthy nodes. The step passes when kubectl reports every control plane node at the target version and etcd members, kube-apiserver, kube-controller-manager and kube-scheduler are healthy. Confirm with the kubeadm documentation for your version which downgrade steps are supported before you begin. If they are not, the rollback point is the verified etcd snapshot.
Drain and upgrade worker nodes
Upgrade worker nodes one at a time. Cordon and drain each node so workloads move to other nodes, respecting PodDisruptionBudgets, then upgrade its kubelet and kubectl packages and restart the kubelet before uncordoning. The version skew policy lets kubelets run up to three minor versions behind kube-apiserver, so you can pause between nodes without leaving the supported range, but the path still ends at the target. The step passes for each node when it reports Ready at the target kubelet version, its pods are running and no disruption budget was violated. If a node fails, halt the rollout and leave the remaining nodes on their current version while you investigate.
Re-scan and repeat for each minor
When every node is at the new minor version, run the deprecation scan again against the new server version, because some APIs are removed only in the release you just reached. Fix anything newly flagged, then take a fresh etcd snapshot and verify it before starting the next minor version. Repeat the control plane and worker steps for the next version on the path. The step passes when the scan is clean for the next target, all nodes are Ready and your smoke tests pass on the current version. The last clean rollback point before each new minor version is the most recent verified snapshot, so record its location in the change log.
What rollback can and cannot undo after an API change
A rollback restores the state you captured, and nothing outside the cluster returns with it. Before you change any API version in a manifest, chart or operator, decide which restore points you will rely on and what each one leaves untouched. The most important distinction is between cluster state held in etcd and everything the cluster depends on outside it: container images in your registry, DNS records, cloud load balancers, storage volumes, certificates issued by external authorities, and databases your workloads write to. An etcd snapshot restore brings back the objects the API server knew about at snapshot time. It does not delete images pushed afterward, roll back DNS changes, recreate cloud resources that were removed, or undo writes that applications made to their own databases after the snapshot.
Restoring etcd is a cluster-wide operation and must be planned as one. The Kubernetes documentation uses etcdctl snapshot save to take backups and etcdutl for restores. Confirm your topology first. In a stacked control plane, etcd members run on the control plane nodes, so the restore involves stopping kube-apiserver and the other control plane components on every node, restoring the snapshot consistently, and bringing members back in the same membership. With an external etcd cluster, the etcd members are separate hosts, and the restore has to be coordinated with the API server nodes that point at them. Plan for an odd number of etcd members, because quorum depends on a majority. The etcd guidance recommends a five-member cluster for production. Confirm with your own runbook and the upstream operations guide how many members you run and which restore steps apply to that layout before an upgrade window opens.
Helm releases and manifests in Git can usually be rolled back more precisely, but only for the objects they describe. Reverting a Git commit that restores an older API version will not work on a cluster where the old version has already been removed by the target release, so check the target version before treating a revert as a safe fallback. For Helm, a previous revision can be reinstated only if the chart version and its rendered objects still deploy on the current API server. Store the rendered output of each release in your change record, not just the chart version, so you know exactly what a revert will apply. Remember that rollback of a Helm release does not revert resources that a chart created outside its manifests, such as custom resources managed by an operator that has since been upgraded.
Decide in advance the point after which a fix cannot be reverted cleanly. This usually occurs once the target control plane version has written objects in the new storage version, once an operator has migrated custom resources, or once workloads have written data that the old version cannot read. Mark that boundary in your upgrade plan, with the checks that confirm you have passed it and the owner who authorizes the next step. Ask your platform team to confirm which fixes are one-way for your installed operators and charts, and test the restore path on a non-production copy of the cluster that matches your topology before you rely on it.
What makes API migration take longer than the upgrade itself
This table lists the factors that most often expand deprecated API work beyond the upgrade step itself, with why each adds effort and how to keep it contained. Use it to size the migration against your own inventory before agreeing on a plan, since most rows scale with the number of clusters, charts and environments you run.
| Driver | Why it adds effort | How to reduce it |
|---|---|---|
| Number of Helm charts and operators | Each chart and operator may pin manifests to a removed API version, and some are vendor-maintained with their own release timing. | Inventory every chart and operator version in every cluster, then confirm which upstream releases support the target API before planning. |
| Custom resources and CRD versions | Operators often serve several CRD versions, and conversion between them must work before the old version is retired. | List each CRD's served and storage versions, and confirm the operator's conversion path with its vendor or project documentation. |
| Unmanaged manifests and GitOps drift | Manifests applied by hand or changed in-cluster are missed by repository scans and get reapplied with old APIs after a fix. | Reconcile live cluster objects against the Git source, and block drift in the sync tool before the scan results are trusted. |
| Air-gapped image mirroring | Replacement controllers and new chart versions need their images and dependencies mirrored into the private registry before they can run. | Build the mirror list from the chart and manifest changes, and verify pulls from a node that has no internet route. |
| Number of clusters and environments | Each cluster has its own inventory, approvals and rollout window, so findings repeat across development, staging and production. | Standardize the scan and fix workflow, and use the same chart versions and values files in every environment. |
| Test coverage in staging | Without workloads exercising the changed APIs, a converted manifest can pass a dry run but fail at runtime. | Add smoke tests for each converted workload and run server-side dry runs against a staging cluster at the target version. |
| Intermediate minor versions on the path | Each minor release can remove APIs, so fixes must be sequenced and rechecked at every step rather than once. | Review the deprecation guide for every minor version between current and target, and track removals in one shared list. |
What buyers ask before paying for Kubernetes API migration help
How much does Kubernetes deprecated API migration help cost?
Cost follows the number of affected objects and how much judgment each one needs, more than the number of clusters alone. Most effort goes to inventory, converting manifests and charts, testing against the target release and fixing operators that ship their own resources. The audit, fixes and test run are one-time work. Recurring cost appears only if you keep a retainer for later upgrades. Drivers that raise cost include many Helm releases with custom values, vendor operators that lag behind the target version and CI pipelines that deploy from old templates. Ask for a written scope that names clusters, namespaces, charts, operators and target versions, and that separates one-time fixes from ongoing support. A quote depends on that written scope, so no figure appears here.
How long does deprecated API migration take before a cluster upgrade?
Duration depends on the target release and on how many components need changes. The Kubernetes project ships about three minor releases a year on a cycle of roughly 14 weeks, and it maintains only the three most recent minor releases, so the window to move is limited. Treat migration as one stage inside the upgrade plan: inventory, fix, test in a non-production cluster, then upgrade. Timelines also depend on chart ownership, vendor response times and change approval in your environment. Ask for a schedule with dated milestones and named dependencies, and check it against the release calendar on the Kubernetes releases page before agreeing to dates.
What does deprecated API migration need from our internal team?
The work needs named owners for each workload, chart and operator, because only those owners can approve changes to their behavior. It also needs read access to the clusters, the Git repositories that hold manifests and the Helm release history, plus a non-production cluster that matches production closely enough to test the target version. Someone with cluster-admin rights must be available for kubectl checks and for reviewing API server audit logs, which can show which clients still call removed APIs. Finally, the team needs a change window and an approver for each fix. Confirm these roles early, because missing owners are a common cause of delay.
Can our in-house team handle deprecated API migration without a partner?
Yes, a small team can do this alone when the estate is small, the charts are mostly in-house and the target release is close to the current one. The main requirements are time to read the deprecation guide for each release, familiarity with kubectl and Helm, and a test cluster. The work becomes harder when many operators come from vendors, when several teams own separate charts or when the cluster has accumulated years of unmanaged resources. In those cases, the cost often shows up as staff time pulled from other projects. Compare your team's capacity against a written inventory of affected objects before deciding.
Can a self-managed Kubernetes cluster skip a minor version during an upgrade?
No, the control plane must move one minor version at a time. The Kubernetes version skew policy says kube-apiserver must be upgraded one minor version at a time, and that kube-controller-manager, kube-scheduler and kubelets follow after it. Kubelets may be up to three minor versions older than kube-apiserver, but that allowance does not permit skipping control plane steps. Each step needs its own deprecated API check, because a removal in an intermediate release can break manifests that worked on the starting version. Plan the migration as a sequence of stops, and confirm the exact steps for your installer and distribution with its documentation.
What should a fixed-scope quote for Kubernetes API migration list?
A fixed-scope quote should list the clusters and namespaces in scope, the source and target Kubernetes versions and the workloads, Helm releases and operators to be checked. It should name deliverables such as an inventory of affected objects, converted manifests, a change log, test results and a rollback plan. Also list the roles your team must fill, the exclusions, such as application code changes or vendor-owned charts, and the acceptance criteria. Include the change windows, the post-upgrade checks and any support period after the upgrade. Finally, ask how one-time work and any recurring retainer are priced, and which assumptions would change the quote.
How do we find manifests and Helm charts that use removed APIs?
Start with three sources: the manifests in your Git repositories, the objects running in the clusters and the rendered output of each Helm chart. Render charts with helm template so you check what the cluster would receive, not only the source files. Use the deprecation guide for the target release to build a list of removed group versions, then search each source for them. Review API server audit logs to find clients still calling those APIs, since some objects may be created by scripts or controllers. Check whether kubectl convert is available and supported for your version before relying on it. Record every finding with an owner and a decision.
Why do Helm charts and operators slow down API migration work?
Helm charts and operators slow the work because their resources are generated, not written by hand. A chart may render an old API version from its templates, so fixing one value does not fix the output. Operators manage custom resources and may install their own deployments, webhooks and CRDs, each of which must support the target release. Vendor-owned charts depend on vendor release schedules, which can fall behind the Kubernetes version you need. Helm release history keeps old manifests, so a rollback can reintroduce a removed API. Confirm each operator's supported Kubernetes versions and each chart's upgrade notes before setting the migration schedule.
How DeployOpen scopes, delivers and supports an API migration and upgrade
DeployOpen starts from the cluster you run today, inventories every manifest, Helm chart and operator that uses an API removed in your target release, and fixes them before the control plane moves. The work runs inside your own cloud accounts, data centers or air-gapped network, and each engagement is fixed-scope with the scope agreed in writing first.
How we scope
- Inventory of cluster objects, Helm releases and operators checked against the target release's removed APIs.
- Written scope names the target Kubernetes version, the repositories and namespaces in scope, and who owns each workload.
- Fixed-scope agreement sets deliverables and timelines before work starts, with ongoing checks available as a retainer.
How we build
- Convert or rewrite each deprecated manifest with kubectl convert and the deprecation guide, then review the output by hand.
- Update Helm charts and operator versions in source control, so each fix is reviewed, versioned and reproducible.
- Test changed workloads in a staging cluster that mirrors production, including admission policies and Pod Security settings.
How we hand over
- Inventory report listing each affected object, its old API version, the replacement and the owning team.
- Change record for every fix, with diffs, test results and a rollback path for each manifest and chart.
- Runbook for the upgrade window, with a pre-upgrade API check your team can rerun before each later minor version.
How we support
- Rerun the API scan when the target release changes, so newly removed APIs are caught before the upgrade window.
- Support after handover can run as a retainer covering upgrades, monitoring of new findings and changes to workloads.
- Upgrade support for later minor versions can be covered by a retainer, scoped in writing like the original work.

