An autoscaling platform that clones a fresh VM, waits for it to check in, then destroys and retries if it doesn't — is genuinely convenient, right up until the clone can never succeed and the platform just keeps trying forever. Here's how to catch the real cause before the evidence gets deleted, and a separate but related lesson about stopping that same churn from starving another VM's disk.
Autoscalers that provision on demand normally show some organic variation — a scale-up here, a scale-down there, timed around actual load. A stuck loop looks different: the same four steps (stop → destroy → clone → start) repeating at an almost perfectly fixed interval, with the identical error message every single time. That regularity is the tell — it means the same timeout is firing on every attempt, not that load genuinely keeps changing.
The hardest part of debugging this kind of loop is that the orchestrator deletes the failing VM as part of its own retry logic — by the time you notice the pattern, the evidence is usually already gone. The fix is to watch for the next clone and inspect it live, before its timeout expires:
In this case, the provisioning script's last line of output was the full text of a software license
agreement, cut off mid-prompt. The install script it called had an interactive
read -p "...accept? (y/n)" step with no default and no way to answer it non-interactively — and
the automatically-generated startup script calling it never passed the install tool's own
"accept license" flag. Every single fresh clone hung there forever: the actual application never started, so
the orchestrator's health check always timed out and destroyed the VM before trying again.
Fix: add the install tool's non-interactive license-acceptance flag to the stored provisioning script, and remove any duplicate/broken command blocks while you're in there. Verify by watching the next clone specifically — the instance already in flight when you find the bug is still running the old broken script (most platforms bake the script in at clone time, not read it live), so it isn't a valid test of your fix.
Once the loop itself is fixed, a second, related problem can remain: if the template being cloned and the destination for every new clone both live on the same physical storage as another active VM, every legitimate clone still generates a real, sizeable read-and-write burst competing with that VM's own disk activity. This is exactly the same class of problem as an NFS bind-mount going unbacked-up — two workloads unknowingly sharing one physical resource.
The fix doesn't have to be moving everything off the shared pool. Reads and writes have very different costs on a mirrored disk pair: a write must complete on every member of the mirror, while a read can be served by whichever member is free. If the platform lets you separate where the source template lives from where new clones' disks actually land, you can:
This resolved real, measured contention: a live clone cycle was shown (via the hypervisor's own storage metrics) to spike write bandwidth on the shared pool to more than ten times its normal baseline, at the exact moment another VM on that same pool needed to write its own data.
Don't trust "the loop stopped" alone — force a fresh test rather than waiting and hoping: