GitHub disables scheduled workflows after 60 days of repo inactivity — silently
If your repository goes 60 days without a push, PR, or manual trigger, GitHub
automatically disables every schedule:-triggered
workflow. No email, no banner until you look, no run history entry. Your nightly
backup, cert renewal, or data sync just stops existing. Dead-man's-switch
monitoring catches "never started" because it expects the signal — and opens an
incident the moment one doesn't arrive.
Three reasons this failure mode is the worst
A workflow that fails loudly is annoying. A workflow that stops silently is catastrophic — and GitHub's design makes silent stops the default.
Zero notification from GitHub
Unlike a failed run (which emails the committer), a disabled schedule triggers nothing. You find out when a backup is missing, a cert expired, or a customer reports stale data — not before.
60 days of false confidence
The previous 59 days of successful runs are still in the history. The workflow looks healthy right up until it disappears. If you're not looking at run frequency, you won't notice.
Any in-workflow ping step can't help
Adding curl ping.lastping.dev/…
as a workflow step doesn't catch this: if the workflow never starts,
the step never executes. Only an external expectation — a
dead-man's-switch — can detect a run that never began.
How to detect it: one webhook, about two minutes
LastPing listens for GitHub's own workflow_run
webhook. When the expected run doesn't arrive in the schedule window, it opens an incident.
No YAML changes, no agent, no GitHub App.
Create a CI check in LastPing
In the console, create a check and choose Monitor a CI/CD pipeline → GitHub. Set the schedule to match your workflow's cron expression exactly, including the IANA timezone. Set a grace window — 30–60 minutes is typical for a daily schedule. Copy the webhook URL and one-time secret.
Register the webhook in your repository
Go to your GitHub repository → Settings → Webhooks → Add webhook:
- Payload URL — the webhook URL from step 1
- Content type —
application/json - Secret — the one-time secret from step 1
- Events — tick Workflow runs only (untick Pushes)
LastPing verifies every delivery's HMAC-SHA256 signature against your secret. No code access required — webhooks are delivered for private repositories exactly as for public ones.
Verify with a manual trigger
Trigger a workflow manually: Actions → your workflow → Run workflow. Within a few seconds the run signal appears in the LastPing console. That confirms the webhook is wired. The next scheduled run will report the same way — and if it doesn't come (because GitHub disabled the schedule), an incident opens automatically.
Re-enable a disabled workflow
Once you know the schedule was disabled, three options to re-enable it:
- Push any commit to the repository (Dependabot bump, README touch, anything)
- GitHub UI: Actions → select workflow → Enable workflow
- GitHub API:
PUT /repos/{'{'}owner{'}'}/{'{'}repo{'}'}/actions/workflows/{'{'}workflow_id{'}'}/enable
What this catches
Dead-man's-switch detection covers every silent failure mode GitHub exposes — not just the 60-day disable.
- Schedule silently disabled — 60 days of repo inactivity causes GitHub to stop firing your schedule. No run signal arrives in the window → incident opens.
- Workflow renamed or deleted — the YAML file was renamed or removed; the schedule no longer exists at all. Same detection: no signal in the window.
- Hung run — the run started (you see a "started" signal) but never completed. LastPing opens an incident when no completion arrives in the grace window.
- Failed run — the webhook delivers a
failureconclusion; an incident opens with a deep link to the exact run. - Recovery — next successful run closes the incident automatically. No manual reset required.
Also affected by silent failures in other CI systems? See the full guide for GitHub Actions monitoring, GitLab CI, and Jenkins — or the complete guide index for cron, Kubernetes, and more. AI agents running on GitHub Actions schedules can be monitored via the LastPing MCP server directly.
Questions people ask
Front-loaded answers — the most important fact first.
-
Why did my GitHub Actions scheduled workflow stop running?
GitHub automatically disables
schedule:-triggered workflows after 60 days without repository activity. There is no notification. The schedule simply stops firing. Check Actions → your workflow for a "This scheduled workflow is disabled" banner. Re-enable by pushing a commit or clicking Enable workflow in the UI. -
Does GitHub send any notification when a scheduled workflow is disabled?
No. GitHub sends no email, webhook payload, or push notification. The only way to know is to look in the UI, check the run history for a gap, or have external dead-man's-switch monitoring in place — the last option is the only one that alerts you before the silence becomes a real problem.
-
Why doesn't adding a curl ping step inside the workflow help?
A
curlping step only executes if the workflow runner picks up the job. If GitHub never fires the schedule (because it was disabled), no runner is allocated, no steps execute, and the ping never happens. You need an external observer that expects the signal — and alerts on its absence. -
How do I prevent this from happening again?
Two complementary strategies: (1) Keep the repository active — a Dependabot bump, a scheduled
workflow_dispatchping, or any commit resets the 60-day clock. (2) Set up dead-man's-switch monitoring with LastPing — so even if the schedule is disabled, you know within one missed window rather than weeks later. -
Is this monitoring free?
Yes. LastPing is free and fully hosted with no monitor cap and no paid tier. See how it compares to Healthchecks.io and Cronitor.
The nightly job you trust most is the one to worry about.
One webhook now beats discovering a missing backup after the fact. First alert wired up in about two minutes — and LastPing monitors itself the same way.