Windows Task Scheduler task didn't run
Task Scheduler records why it did not run, but the history is off by default and the result codes are not obvious. Here is how to read them.
Task Scheduler is more informative than cron, but only once you turn the information on. By default the history is disabled, and the codes it reports are hexadecimal Win32 errors with no explanation attached.
1. Turn on history first
Open Task Scheduler, select Task Scheduler Library in the left pane, and click Enable All Tasks History in the Actions pane on the right. If the link says Disable, history is already on.
History is off by default, and it is not retrospective: turning it on now tells you nothing about last night. Turn it on before you need it.
With history on, select the task and open the History tab. Event 106 is a task registered, 100 is a launch, 102 is a completed action, 101 is a failed launch, and 111 is a task terminated. The same records are in Event Viewer under Applications and Services Logs → Microsoft → Windows → TaskScheduler → Operational.
2. Read the Last Run Result
The codes that account for most cases:
0x0— the action completed and returned success. This says nothing about whether it did the right thing.0x1— the program returned 1. This is your script's failure, not Task Scheduler's; look at the script.0x2— file not found. Usually a wrong path in Program/script.0x41301— the task is currently running. A task that shows this permanently has a previous instance stuck.0x41303— the task has never run. The trigger has not fired, or is misconfigured.0x41306— the task was terminated, typically by the Stop the task if it runs longer than setting on the Settings tab.0x8007010B— directory name is invalid. Almost always an empty or wrong Start in field.
3. The three configuration traps
Start in must be set, and must not be quoted. The Start in (optional) box on the action sets the working directory. A script that uses relative paths fails without it, and unlike every other path field in Windows, this one must not be wrapped in quotation marks.
"Run whether user is logged on or not" needs a password that still works. Choosing it stores the account's credentials. When that password is changed, expires, or is reset by policy, the task stops running and reports a logon failure. Tasks set up under a personal account are the ones that silently die months later. A service account with a non-expiring password, or a machine account, avoids it.
The Conditions tab quietly blocks tasks. By default, Start the task only if the computer is on AC power and Stop if the computer switches to battery power are both ticked. On a laptop that is enough to explain everything. Start only if the following network connection is available behaves the same way on a machine that connects late.
4. The machine was asleep or off
A trigger that fires while the computer is off does not queue. Two settings change that: Run task as soon as possible after a scheduled start is missed on the Settings tab, and Wake the computer to run this task on Conditions. Neither is on by default.
5. Capture what the script printed
Task Scheduler records the exit code and nothing else. Redirect output in the action itself so there is something to read:
Program/script: powershell.exe
Arguments: -NoProfile -ExecutionPolicy Bypass -File "C:\jobs\export.ps1" *> "C:\logs\export.log"
Start in: C:\jobs
Knowing when the task stops running
Enabled history tells you about a launch that happened. It cannot tell you about the night the machine was off, the week after the stored password expired, or the day somebody disabled the task. Those produce no events at all.
Have the task report success to an external URL, and be alerted when the report stops:
C:\jobs\export.ps1
if ($LASTEXITCODE -eq 0) {
Invoke-RestMethod -Uri "https://vivere.dev/p/<your-monitor-id>" -TimeoutSec 10
}
Or report the exit code either way, so a failure alerts immediately:
C:\jobs\export.ps1
Invoke-RestMethod -Uri "https://vivere.dev/p/<id>/$LASTEXITCODE" -TimeoutSec 10
Common questions
How do I see why a scheduled task did not run?
Open Task Scheduler, select the task, and enable All Tasks History from the Actions pane if it is off, which it is by default. The History tab then records each launch attempt and its result. Without history enabled, nothing is recorded and the Last Run Result is all you have.
What does last run result 0x41303 mean?
0x41303 means the task has never run. It usually appears on a task that was created but whose trigger has not fired yet, or whose trigger is misconfigured, rather than on one that failed.
Why does my task run when I am logged in but not otherwise?
The task is set to run only when the user is logged on, or it is set to run whether logged on or not but the stored password is stale after a password change or a policy reset. A task that runs under a user account with a stored credential stops silently the day that credential stops working.
Find out without looking
Vivere watches for the ping that does not arrive. Add one line to the job, pick where alerts should land, and you hear about the run that never happened.
Start free Read the quickstart
Ten monitors, a status page, email and webhook alerts. No card.
Last reviewed September 2026.
Related
- Cron job not running: how to find out why — A cron job stopped running and nothing told you. The five usual causes in the order worth checking, how to read the logs, and how to find out next time without looking.
- How to know if your backup actually ran — Backups fail quietly. How to verify a backup ran, why exit code zero is not proof, what to check about size and restore, and how to be told the night it does not happen.
- A dead man's switch for your scripts — What a dead man's switch is, why it catches failures that error-based alerting cannot, how to build one with cron and curl, and the timing rules that stop it crying wolf.