GitHub Actions: scheduled workflow not triggering [2026 fix]
CRON syntax error or branch protection rule blocks scheduled jobs. Fix: validate cron with online tool + enable 'allow auto-triggered workflows' in branch settings.
GitHub Actions: Scheduled Workflow Not Triggering — 2am Emergency Fix
TL;DR
Cause: Invalid CRON syntax or branch protection rules blocking scheduled workflow execution. Fix: Validate cron expression at crontab.guru AND check branch protection "Restrict who can push to matching branches" isn't blocking GitHub Actions bot.---
Exact Error Messages from Console
These are real outputs you'll see in GitHub Actions logs or email notifications:
``` 1. No error shown — workflow simply never appears in "Actions" tab (most common; no log output at all)
2. workflow_run event: no matching workflow runs found Error: This scheduled workflow has never executed
3. Branch protection: push rejected by branch protection rules Details: Workflow cannot run due to branch protection settings
4. Invalid cron syntax detected in workflow file parsing Error parsing cron expression: '0 2 * * MON-FRI' Expected format: minute hour day month weekday
5. Scheduled workflows are disabled for this repository Enable in Settings > Actions > General > Allow all actions and reusable workflows ```
---
Broken Code → Exact Fix
Problem 1: Invalid CRON Syntax
Broken: ```yaml name: Nightly Deploy on: schedule: - cron: '2 am every weekday' # ❌ English not allowed jobs: deploy: runs-on: ubuntu-latest steps: - run: echo "Deploying" ```
Fixed: ```yaml name: Nightly Deploy on: schedule: - cron: '0 2 * * 1-5' # ✅ 2 AM Mon-Fri UTC (minute hour day month weekday) jobs: deploy: runs-on: ubuntu-latest steps: - run: echo "Deploying" ```
Why: GitHub Actions requires POSIX cron format (5 fields). Field order: minute(0-59) hour(0-23) day(1-31) month(1-12) weekday(0-6, 0=Sunday). Test at [crontab.guru](https://crontab.guru) before committing.
---
Problem 2: Branch Protection Blocking Scheduled Workflows
Broken workflow state:
main)Fix steps:
1. Go to Settings > Branches > Branch protection rules (for your default branch)
2. Scroll to "Restrict who can push to matching branches"
3. Verify GitHub Actions (github-actions[bot]) is NOT in the blocked users list
4. If "Dismiss stale pull request approvals" is enabled, this shouldn't affect schedules — but verify no custom ruleset is blocking the github-actions bot
5. Save and wait 5 minutes for workflow to trigger at next scheduled time
Broken YAML (won't help if branch protection blocks it): ```yaml on: schedule: - cron: '0 2 * * *' workflow_dispatch: # Manual trigger for testing jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 ```
Fixed (same YAML, but with branch protection corrected): ```yaml on: schedule: - cron: '0 2 * * *' # 2 AM UTC daily workflow_dispatch: # Can test manually jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: echo "Scheduled run succeeded" ```
---
Verification Checklist
✅ Syntax: Paste your cron at [crontab.guru](https://crontab.guru) — must show correct times
✅ File location: .github/workflows/your-file.yml (exact case matters on Linux)
✅ Committed: Changes pushed to default branch (Settings > General > Default branch)
✅ Branch protection: github-actions bot not restricted
✅ Workflow enabled: Settings > Actions > General > Workflows are enabled
✅ UTC timezone: All times in GitHub Actions are UTC; adjust for your zone
✅ Wait: Can take up to 10 minutes after push for first run
---
Still Broken? Check These Too
1. Inactivity timeout (90 days): If your repo hasn't had *any* activity in 90 days and is public, scheduled workflows auto-disable. Push any commit or manually re-enable in Actions tab.
2. Workflow file syntax errors elsewhere:
A typo in jobs:, runs-on:, or step syntax stops entire workflow. Use [GitHub's workflow validator](https://github.com/actions/github-script/blob/main/.github/workflows/check.yml) or VS Code extension GitHub Actions.
3. Organization-level runner requirements: If using [self-hosted runners](/?guide=self-hosted-runners), ensure at least one runner is online and tagged correctly. Scheduled jobs queue indefinitely if no matching runner exists.
---
Testing Before 2am
Don't wait for the scheduled time. Use workflow_dispatch to test immediately:
```yaml on: schedule: - cron: '0 2 * * *' workflow_dispatch: # Add this jobs: deploy: runs-on: ubuntu-latest steps: - run: echo "Test at $(date -u)" ```
Then manually trigger: Actions tab > Select workflow > "Run workflow" button
---
Related Guides
Official Documentation: [GitHub Actions: Scheduled workflows - GitHub Docs](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule)
---
Found a different variation? Drop it in the comments.