Deployment Timeouts & Automatic Finalization
When you push a software deployment to a set of agents, Athena tracks it as an execution that stays in the Running state until every targeted agent reports a result. If one or more agents never report back — because a machine is powered off, drops off the network, or the job hangs — the execution would otherwise sit in Running indefinitely. To prevent that, Athena runs a background watcher that automatically finalizes stale deployments once they exceed the deployment timeout. This page explains how the timeout is applied, what result a non-reporting agent receives, and how the overall deployment status is decided.
The deployment timeout described here is the ceiling for a whole
deployment execution — how long Athena waits for agents to report before it gives up on the
stragglers. It is not the same as the per-step timeoutSeconds that bounds a
single command or install step inside a package. For per-step timeouts, see
Deployment Package Steps.
How the deployment timeout works#
Every deployment execution records when it started. A background watcher on the server wakes up about every two minutes and looks for executions that are still in the Running state but whose start time is older than the deployment timeout. Each execution it finds is finalized immediately — the watcher does not wait for the next cycle.
- The watcher starts a short time after the server comes up and then runs continuously in the background; there is nothing to enable or schedule.
- Only executions still marked Running are candidates. Deployments that have already reached a terminal state (Completed, Failed, Partial success, Cancelled, Rejected) are left untouched.
- A failure while finalizing one execution does not stop the sweep — the remaining stale executions in the same cycle are still processed.
What happens to agents that never report#
When an execution exceeds the timeout, Athena compares the agents that were targeted against the agents that have already reported a result. Results that already arrived are always kept — the timeout never overwrites a real outcome. For every targeted agent that has not reported, Athena writes a synthetic result so the deployment can be closed out:
| Field | Value recorded for a timed-out agent |
|---|---|
| Status | Failed |
| Exit code | -1 |
| Error output | Agent timed out — did not report back within N minutes, where N is the deployment timeout in effect |
| Completed at | The time the watcher finalized the execution |
Once the missing agents are marked failed, the execution is finalized and moves out of the Running state. If an execution is somehow still Running even though all of its agents have already reported, the watcher simply recomputes and closes out the overall status — no false failures are added.
How the overall status is decided#
After the per-agent results are settled, Athena rolls them up into a single deployment status that you see on the Deployments screen:
| Overall status | Meaning |
|---|---|
| Completed | Every targeted agent succeeded. |
| Failed | Every targeted agent failed (including agents that timed out). |
| Partial success | Some agents succeeded and some failed — for example, most machines installed the package but a few were offline and timed out. |
This is why a deployment sent to a mix of online and offline machines typically settles as Partial success: the machines that were reachable report their real result, and the machines that never came online are recorded as timed-out failures once the deployment timeout is reached. You can open the execution to see the per-agent breakdown and the timeout error text on each affected agent.
Setting the deployment timeout#
The timeout is a server-wide default. Its configuration key is
Scheduler:DefaultDeploymentTimeoutMinutes and the default is 120
minutes (two hours). Raise it for deployments to fleets that include machines which are often
powered off overnight; lower it if you want stragglers written off sooner.
// appsettings.json
"Scheduler": {
"DefaultDeploymentTimeoutMinutes": 180
}
The equivalent environment variable is
Scheduler__DefaultDeploymentTimeoutMinutes. Because the watcher re-reads the value
on every cycle, the new timeout applies to executions still Running as well as new ones.
You do not have to edit the configuration file by hand. The same value is the Default Deployment Timeout field under Settings → Scheduler. See Scheduler Settings for the full tab.
REST API#
The deployment timeout is part of the scheduler settings and can be read or changed over the
JWT-authenticated REST API on port 8443. Send the bearer
token as Authorization: Bearer <token>; both endpoints require the Admin role.
| Endpoint | Role | Purpose |
|---|---|---|
GET api/settings/scheduler | Admin | Read the current scheduler settings, including defaultDeploymentTimeoutMinutes. |
PUT api/settings/scheduler | Admin | Update the scheduler settings. Send the full settings object. |
# Read the current scheduler settings
curl -k -H "Authorization: Bearer <token>" \
https://athena.example.com:8443/api/settings/scheduler
# Raise the deployment timeout to 3 hours (send the full object you read back)
curl -k -X PUT -H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"defaultCommandTimeoutMinutes": 10,
"defaultDeploymentTimeoutMinutes": 180,
"maxConcurrentJobs": 10,
"historyRetentionDays": 30,
"cleanupInactiveDays": 30,
"collectionRefreshIntervalMinutes": 5,
"commandRetentionDays": 30,
"cronBuilderMode": "Visual"
}' \
https://athena.example.com:8443/api/settings/scheduler
PowerShell#
The Athena PowerShell module reads and writes the deployment
timeout through the Scheduler settings category. Sign in with
Connect-Athena as an Admin first.
# Connect as an Admin
Connect-Athena -Server "athena.contoso.com"
# Read the current deployment timeout
$scheduler = Get-AthenaSettings -Category Scheduler
$scheduler.DefaultDeploymentTimeoutMinutes
# Give overnight fleets more time before stragglers are written off
$scheduler.DefaultDeploymentTimeoutMinutes = 240
Set-AthenaSettings -Category Scheduler -Settings $scheduler
Set-AthenaSettings supports -WhatIf/-Confirm, so you can
preview the change or gate it in a script.
Troubleshooting#
| Symptom | Explanation / what to do |
|---|---|
| A deployment shows Failed on some agents with the message “Agent timed out — did not report back within N minutes” | Those agents never reported a result before the deployment timeout elapsed. Confirm the machines are powered on and connected, then re-target them with a new deployment. |
| A deployment auto-changed to Partial success after a couple of hours | Expected when some agents were offline. The reachable agents reported real results; the offline ones were finalized as timed-out failures once DefaultDeploymentTimeoutMinutes was exceeded. |
| A deployment is stuck in Running and I don’t want to wait | You can end it yourself from the Deployments screen (Cancel) instead of waiting for the timeout. Otherwise the watcher will finalize it on its next cycle once the timeout is reached. |
| Deployments to laptops keep timing out overnight | Increase Scheduler:DefaultDeploymentTimeoutMinutes so the window covers the time machines are likely to come back online. |
Related#
- Software Deployment — create, target, schedule, and monitor deployments.
- Deployment Package Steps — per-step timeouts, success exit codes, and continue-on-error inside a package.
- Scheduler Settings — the Settings tab that holds the deployment timeout alongside the other background-work defaults.
- Maintenance Mode — how paused agents affect what reaches a machine.
- Configuration — the full appsettings.json reference.