Skip to content
Latchkey

Self-Healing CI: Auto-Retrying a Transiently Timed-Out Step

A step that blows its time budget once and then passes on a clean retry was slow, not stuck - a transient slowdown, not a real hang.

The problem

A step is cancelled for exceeding its timeout, but the very next run completes well within the limit. Nothing changed in the code; a transient slowdown (a slow download, a busy dependency, a cold cache) pushed that one run over the edge. A human re-runs the job and it passes.

Typical symptom
##[error] The action has timed out.
# or
Error: Step exceeded the timeout of 600 seconds and was cancelled.

Why it happens

A timeout is a single threshold against wall-clock time, so any transient slowdown - a slow registry, a cold cache, brief CPU contention on a shared host - can push an otherwise-healthy step past the line on one run and not the next.

When the next run finishes comfortably under the same limit, the timeout was the symptom of a one-off slow moment, not a genuine deadlock or infinite loop.

The manual fix

Manual handling for a transient timeout:

  1. Re-run the job and confirm it completes within the limit.
  2. Warm caches and pin/mirror dependencies so the slow path is faster and steadier.
  3. Raise the timeout only enough to absorb normal variance - not so high that a real hang goes unnoticed.

How this gets automated

A transient timeout is distinguishable from a genuine hang by whether a retry completes in budget, so the safe response is a bounded retry. A self-healing CI pipeline retries a step that timed out transiently, and surfaces it only if it times out repeatedly - which is the real signal of a deadlock or runaway loop rather than a slow moment.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →