Windows Task Scheduler not running: read the Last Run Result, then fix the cause
A scheduled task that did not run leaves one clue: its Last Run Result. The table below gives Microsoft's meaning for the codes you are likely to see, then the usual causes behind them. Finish with a PowerShell wrapper that pings LastPing, so the next task that fails or never starts opens an incident instead of waiting to be noticed.
Your assistant can do this for you
Find out why my Windows scheduled task is not running, and monitor it with LastPing
On this page
Check these first
Task Scheduler records the last result of every task. Read it before changing anything.
# Last run, its result, the next run and how many runs were missed
Get-ScheduledTaskInfo -TaskName 'Nightly backup'
# The same from cmd.exe, with every setting
schtasks /query /tn "Nightly backup" /v /fo list
In the Task Scheduler window, the Last Run Result column and the History tab show the same. If the History tab is empty, history may be turned off: Enable All Tasks History in the Actions pane turns it on.
Last Run Result codes, and what they mean
Task Scheduler's own codes start with 0x4 (success and status) or 0x8004 (errors). The meanings below are Microsoft's, from the Task Scheduler error and success constants; they are written here without their leading zeros, so 0x00041301 appears as 0x41301.
| Result | Constant | Microsoft's description |
|---|---|---|
| 0x0 | The last run returned 0. For a script or program, look up what that value means in its own exit codes. | |
| 0x41300 | SCHED_S_TASK_READY | The task is ready to run at its next scheduled time. |
| 0x41301 | SCHED_S_TASK_RUNNING | The task is currently running. |
| 0x41302 | SCHED_S_TASK_DISABLED | The task will not run at the scheduled times because it has been disabled. |
| 0x41303 | SCHED_S_TASK_HAS_NOT_RUN | The task has not yet run. |
| 0x41304 | SCHED_S_TASK_NO_MORE_RUNS | There are no more runs scheduled for this task. |
| 0x41305 | SCHED_S_TASK_NOT_SCHEDULED | One or more of the properties that are needed to run this task on a schedule have not been set. |
| 0x41306 | SCHED_S_TASK_TERMINATED | The last run of the task was terminated by the user. |
| 0x41307 | SCHED_S_TASK_NO_VALID_TRIGGERS | Either the task has no triggers or the existing triggers are disabled or not set. |
| 0x8004131F | SCHED_E_ALREADY_RUNNING | An instance of this task is already running. |
| 0x80041320 | SCHED_E_USER_NOT_LOGGED_ON | The task will not run because the user is not logged on. |
| 0x80041324 | SCHED_E_TASK_ATTEMPTED | The Task Scheduler service attempted to run the task, but the task did not run due to one of the constraints in the task definition. |
| 0x80041326 | SCHED_E_TASK_DISABLED | The task is disabled. |
| 0x8004131E | SCHED_E_PAST_END_BOUNDARY | The task cannot be started after the trigger's end boundary. |
| 0x80041315 | SCHED_E_SERVICE_NOT_RUNNING | The Task Scheduler Service is not running. |
| 0x800710E0 | Windows error 4320, ERROR_REQUEST_REFUSED | The operator or administrator has refused the request. |
A value that is not in this table, such as 0x1 or 0x2, is not one of Task Scheduler's own codes. Last Run Result shows the value the last run returned; for a script or program, look up what that value means in its own exit codes, and run the same command by hand to see its output. Microsoft notes that some results are Windows system error codes, which net helpmsg explains: net helpmsg 64, the example Microsoft gives, prints: The specified network name is no longer available. A result that starts with 0x8007 wraps a Windows error code in its last four hex digits, as 0x800710E0 wraps 4320.
Eight reasons a scheduled task does not run
In the order worth checking. The defaults quoted are Microsoft's.
The task is disabled or has no trigger that fires
0x41302 and 0x80041326 mean the task is disabled; 0x41307 means it has no trigger, or every trigger is disabled; 0x41304 means no more runs are scheduled, for example after a trigger's end date. Enable the task and check the Triggers tab.
It only runs while you are logged on
With Run only when user is logged on, a task scheduled while nobody is signed in does not start, and the result reads 0x80041320: "The task will not run because the user is not logged on." Choose Run whether user is logged on or not on the General tab.
The laptop was on battery
A new task does not start on battery power: DisallowStartIfOnBatteries defaults to true ("The default is True"). In the Conditions tab, clear Start the task only if the computer is on AC power if it must run anyway. The task can also be set to stop when the computer switches to battery.
The computer was off or asleep at the scheduled time
A missed start is skipped unless Run task as soon as possible after a scheduled start is missed is set. That setting, StartWhenAvailable, defaults to false; when it is on, the late start is queued and begins after a delay, 10 minutes by default. Wake the computer to run this task is the other way round it.
The last run is still going
0x8004131F, "An instance of this task is already running", comes from the multiple-instances setting: Task Scheduler can run a new instance in parallel, queue it, not start it, or stop the existing one. A run that hangs blocks every scheduled run after it under "do not start a new instance". By default a task is also stopped 72 hours after it starts.
PowerShell refuses to run the script
Execution policy can block scripts: when no policy is set in any scope, the effective policy on a Windows client is Restricted, which allows commands but no scripts. Run the script with the policy set for that one process, and give the full path:
Program/script: powershell.exe
Add arguments: -NoProfile -ExecutionPolicy Bypass -File "C:\jobs\nightly.ps1"
Start in: C:\jobs
Relative paths point somewhere else
A script that reads .\config.json or writes logs\out.txt resolves those paths against the action's working directory, which is not the script's folder unless you set it. Fill in Start in (optional) on the action, or use full paths.
A condition held it back
0x80041324 means Task Scheduler tried to run the task, "but the task did not run due to one of the constraints in the task definition": the Conditions tab (idle, AC power, network) and the Settings tab are where those live.
Get alerted when a task does not run
Last Run Result only helps when someone looks at it. A ping from the task, checked against the schedule outside the machine, reports the run that failed and the one that never started.
Create a monitor with the task's schedule
In the console, create a monitor whose schedule matches the trigger, for example 0 2 * * * for daily at 02:00, in the timezone the trigger uses, plus a grace window. Copy the ping URL.
Wrap the job in a PowerShell script
The script pings /start, runs the work, then pings success or posts the error to /fail. Each ping has its own try, so a network hiccup never turns a good run into a failed one:
# C:\jobs\nightly.ps1
$ping = 'https://ping.lastping.dev/<your-monitor-id>'
function Send-Ping([string]$suffix = '', [string]$body = '') {
try {
if ($body) {
Invoke-RestMethod "$ping$suffix" -Method Post -Body $body -ContentType 'text/plain' -TimeoutSec 10 | Out-Null
} else {
Invoke-RestMethod "$ping$suffix" -TimeoutSec 10 | Out-Null
}
} catch {}
}
Send-Ping '/start'
try {
& 'C:\jobs\backup.exe' --target D:\backups
if ($LASTEXITCODE -ne 0) { throw "backup.exe exited with code $LASTEXITCODE" }
Send-Ping
} catch {
Send-Ping '/fail' $_.Exception.Message
exit 1
}
The action then runs powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\jobs\nightly.ps1", as shown above. exit 1 keeps the failure visible in Last Run Result too.
Or append one line to a batch file
LastPing also takes the exit code as the last part of the URL: 0 is success, anything else a failure. With curl.exe on the machine:
C:\jobs\backup.exe --target D:\backups
curl.exe -fsS -m 10 --retry 3 -o NUL https://ping.lastping.dev/<your-monitor-id>/%ERRORLEVEL%
What this catches
The script reports what it can see; the schedule reports the silence.
- Never started: a disabled task, a user not logged on, battery power, a computer that was off, a condition that held it back or a script blocked by execution policy. No ping in the window opens an incident.
- Failed: a non-zero exit code or an exception posts to
/fail, and the alert goes out at once with the message on the incident. - Hung: the start ping arrived and the finish did not, so overrun detection opens an incident long before the 72-hour default stops the task.
- The machine is gone: a dead disk, a reinstalled server or a laptop left in a drawer sends nothing, and that silence is an incident too.
- Recovery: the next successful run closes the incident and sends a recovery notice.
Questions people ask
Front-loaded answers: the most important fact first.
-
Why is my scheduled task not running?
Read its Last Run Result first. The usual causes: the task is disabled or has no active trigger, it is set to run only when the user is logged on, the computer was on battery or switched off at the scheduled time, an earlier run is still going, or PowerShell's execution policy blocked the script.
-
What does Last Run Result 0x1 mean?
0x1 is not one of Task Scheduler's own codes. Last Run Result shows the value the last run returned; for a script or program, look up what that value means in its own exit codes. Run the same command by hand, as the same user and in the same Start in folder, and read its output.
-
What does 0x41301 mean in Task Scheduler?
SCHED_S_TASK_RUNNING: the task is currently running. If it stays there long after the job should have finished, the run is hung, and with the do not start a new instance setting it also blocks the next scheduled runs.
-
What does 0x41303 mean in Task Scheduler?
SCHED_S_TASK_HAS_NOT_RUN: the task has not yet run. Check that a trigger is enabled and its start time is in the past, and that the computer was on and allowed to run it.
-
What does 0x80041320 mean?
SCHED_E_USER_NOT_LOGGED_ON: the task will not run because the user is not logged on. Set the task to Run whether user is logged on or not.
-
How do I get alerted when a scheduled task fails or does not run?
Wrap the job in a PowerShell script that pings LastPing's /start URL, then the monitor URL on success or /fail with the error. Give the monitor the task's schedule and a grace window, and a task that never starts opens an incident too.
-
Is this monitoring free?
Yes. LastPing is free for individuals with no monitor cap. See how it compares to Healthchecks.io and Cronitor.
Last Run Result waits for someone to look. This doesn't.
One wrapper script now beats finding a month of missing backups later. First alert wired up in minutes, and LastPing monitors itself the same way.