CKS: concurrent operations clobber a cluster's state, and a management server restart leaves it stuck in a transient state · Issue #14608 · apache/cloudstack · GitHub
Two related problems with the state of a CKS (Kubernetes Service) cluster.
Concurrent operations clobber each other. KubernetesClusterDaoImpl.updateState writes the new state by id without checking the current state (it even carries a TODO: ensure this update is correct). Two operations started on the same cluster at the same time therefore both get past their first transition, for example a scale and an upgrade, or two scales. Each then runs its steps against VMs that the other is changing, and whichever finishes last decides the final state. Workers also ignore a failed entry transition and carry on. So does an operation started in a state with no transition for it, for example adding nodes to a cluster that is being scaled. The status scanner can likewise overwrite the state of an operation that started after it listed the cluster. For example, its Alert reconciliation can stop a cluster that a user has just started.
A cluster stays stuck in a transient state after a management server restart. If the management server running an operation stops partway through (a restart, a crash, an upgrade), the cluster stays in that operation's state: Scaling, Upgrading, Starting, Importing, RemovingNodes and so on. The async job is failed when the management server comes back, or when a peer sees it leave, but nothing moves the cluster on. Every later operation on it is then refused, and the cluster can only be fixed by editing the database. The scanner's first-run handling of Starting clusters tries FaultsDetected, a transition that does not exist from Starting, so it does not help for running clusters either.
versions
4.22 (the code is the same on main).
The steps to reproduce the bug
Concurrent operations:
Take a running CKS cluster.
Call scaleKubernetesCluster and upgradeKubernetesCluster (or two scaleKubernetesCluster calls) at the same time.
Both are accepted and both run against the cluster's VMs. The cluster ends in whatever state the last one to finish leaves.
Stuck state:
Start a long CKS operation, for example a scale-up or an upgrade.
Restart the management server running the job while it is in progress.
The job is failed, but the cluster stays in Scaling / Upgrading forever, and start, stop, scale and upgrade are all refused.
What to do about it?
Make the state update a compare-and-set on the current state, as the VM and volume DAOs already do.
Have each operation move the cluster into its own state before it changes anything, and fail cleanly when another operation got there first.
Have the status scanner fail the operation of any cluster that is in an operation's state while no job is in progress for it on any management server. The existing Alert reconciliation can then return a healthy cluster to Running.
threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.
What happened
The threat detection engine failed to produce results.
Two CKS state problems. First, KubernetesClusterDaoImpl.updateState writes by id without checking the current state, so two operations started together (for example a scale and an upgrade) can both proceed. Second, if the management server running an operation stops partway, the cluster stays in that operation's transient state, and the scanner's handling of Starting clusters tries a transition that does not exist. The reporter proposes compare-and-set updates, moving to the operation's state before any change, and having the scanner fail operations that have no job running.
📊 Assessment
Dimension
Value
Reasoning
Type
type:bug
Race condition and stuck state after restart, with reproduction steps
Component
component:cks
CKS cluster state DAO, workers and status scanner
Severity
Severity:Major
Clusters can become stuck and only be fixed by editing the DB
Labels
type:bug, component:cks, Severity:Major
Coding agent
Not suitable
Cross-cutting state-machine and concurrency change needing maintainer design
Activity
github-actions commented on Nov 9, 2026
Warning
threat detection engine error
What happenedThe threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.
The threat detection engine failed to produce results.
Review the workflow run logs for details.
🎯 Triage report
Two CKS state problems. First, KubernetesClusterDaoImpl.updateState writes by id without checking the current state, so two operations started together (for example a scale and an upgrade) can both proceed. Second, if the management server running an operation stops partway, the cluster stays in that operation's transient state, and the scanner's handling of Starting clusters tries a transition that does not exist. The reporter proposes compare-and-set updates, moving to the operation's state before any change, and having the scanner fail operations that have no job running.
📊 Assessment
🔗 Similar issues
- CKS: a cluster in Alert can't be scaled, so one stopped node blocks scaling and the cluster-autoscaler #14603 (related) — CKS cluster in Alert cannot be scaled
- CKS: node drain on scale-down and upgrade fails too easily, and a failed upgrade can't be resumed #14610 (related) — failed upgrade cannot be resumed
- CKS: Kubernetes nodes report stale CPU/RAM capacity after live resize #14213 (related) — CKS nodes report stale capacity after live resize
💡 Notes and suggestions- The TODO: ensure this update is correct in updateState is the place to start.
- Reproduction for the race: call scaleKubernetesCluster and upgradeKubernetesCluster on a running cluster at the same time.
Add this agentic workflow to your repoTo install this agentic workflow, run