Motoko timer fix targets cycle-starved self-calls in PR #6440
An open Motoko pull request retries timer work rejected for low cycles. Track PR #6440, and check timer liveness and cycle balances in deployed canisters while the fix awaits review.

On October 7, 2026, a Motoko forum thread linked timer failures during low-cycle conditions to open PR #6440. Motoko canister teams should track the PR and check timer liveness and cycle balances while the fix awaits review.
What changed: the failure is in timer dispatch
The thread began with a developer reporting that timers stopped after a canister froze for lack of cycles and did not resume after a top-up. The developer said this had happened “around 15 times” and described cases where recovering an older canister meant rebuilding and upgrading it. The thread proposed a platform behavior called “cryostasis”: retain timers during a freeze and resume them when the canister can run again.
Later replies narrowed the issue. A post on August 13 said a pending global timer should be retained while the canister is frozen, then run after a top-up. It also pointed to a Motoko timer failure path: the global timer fires, Motoko sends a self-call to run the helper, and that call can be rejected for lack of cycles. If the helper never runs, it cannot schedule the next timer. The queue may remain in memory, but no timer is left to wake it.
On October 7, the thread author pointed to Motoko pull request #6440 as the fix in progress. The PR adds a fallback global timer for the default Motoko timer handler, set to “now + 5 seconds” before it sends the helper call. If the helper call is rejected, the fallback can fire again after the canister receives cycles. The helper replaces the fallback with the next actual deadline when it runs.
The PR also changes how the helper handles one-shot jobs. It reinserts a job if its self-call is rejected with #system_transient, which indicates the job did not run. Recurring jobs are already rescheduled, so the fix skips missed runs instead of replaying them after recovery. This is a Motoko runtime fix, not a change to the Internet Computer protocol’s global timer rules. The IC interface specification says the global timer is deactivated when a canister runs out of cycles and must be set again for canister_global_timer to be scheduled.
Who is affected and why it matters
The immediate audience is teams using Motoko’s default timers for scheduled work. A helper self-call can fail asynchronously after being sent, so code that only handles an immediate failure may miss the rejection. The result can look like a timer queue was erased: funding the canister restores its ability to run, but without a scheduled wake-up the helper does not execute to resume the queue.
This can delay recurring maintenance and one-shot work in applications that depend on timers. The fix’s retry policy also matters: one-shot jobs rejected before execution are reinserted, while recurring jobs skip the missed invocation and continue their schedule. Developers should account for that behavior in jobs that must process every interval or catch up after an outage.
The forum thread also includes a separate Rust CDK diagnosis. A Rust developer reported a reproduction on “PocketIC 15” with “ic-cdk 0.19” and “ic-cdk-timers 1.0.0”; they found that calling set_timer_interval again could be a no-op when the CDK cache held an earlier deadline. They recommend a raw global timer reset for that Rust case. This is useful context, but it is not the Motoko PR’s fix and should not be applied as a generic Motoko recovery recipe.
What to do now
- Check the status of Motoko PR #6440 before planning an upgrade. As of October 9, it was open and awaiting a requested review; there was no released compiler version containing the fix.
- For affected Motoko deployments, keep an external check on cycles and on whether timer-driven work is advancing. The thread suggests exposing a timer counter or timestamp that an outside monitor can read, since a canister with a dead timer cannot report its own failure.
- Review timer callbacks for missed-run behavior. Make callbacks safe to retry, and decide whether a missed recurring interval should be skipped or recovered through separate application state.
- After the PR is merged and included in a Motoko release, build and deploy with that release, then verify behavior on a test canister that is starved of cycles and topped up. The PR describes tests for rejected helper calls and one-shot jobs; do not assume those changes are already in a published compiler.
The official upgrade guidance separately warns that timers are deactivated during upgrades and need to be set up again. Treat upgrades and low-cycle recovery as distinct paths when reviewing timer initialization and recovery logic.
Caveats
PR #6440 was still in review on October 9, 2026. Its described fix targets Motoko’s default timer handler; the PR explicitly leaves user-defined system func timer behavior for separate work. The forum discussion also records different observed behavior across environments, so the thread does not establish that every frozen canister loses timers in the same way.
Get the wire in your inbox
Every new signal, straight from the generator. No noise, unsubscribe anytime.


