Safeguard
Developer Tools•

How should security automation jobs handle timeouts and failures?

Set timeout-minutes, decide which steps may fail without failing the job, and alert on failure so silence is never read as a clean scan. A policy table.

Safeguard Security Team
4 min read

Set an explicit timeout-minutes on every job, decide per step whether failure should stop the job, and alert when the automation itself fails. The default job timeout in GitHub Actions is 360 minutes, which is far too long for a notification script.

The defaults

GitHub's workflow syntax reference says the job level timeout-minutes is the maximum number of minutes to let a job run before GitHub cancels it, with a default of 360. A step level timeout-minutes kills the step process after the limit, with a documented maximum of 360, and the value must be a positive integer. There is also continue-on-error, which prevents a job from failing when a step fails.

A hung HTTP call to a ticketing system can therefore sit for six hours, hold a concurrency slot and block the next run. Short limits make hangs visible.

Choose limits by job type

JobSuggested job timeoutReason
Chat notificationA few minutesOne HTTP call
Ticket sync10 to 15 minutesMany small calls
Dependency scanBased on your longest normal run, plus marginCatch runaway scans
Weekly report20 to 30 minutesGathers data from several sources

Look at the last twenty successful runs and set the limit at about double the slowest. Revisit when the repository grows.

Which steps may fail quietly

The question to ask per step is: if this fails, is the result still trustworthy?

  • Scan step fails: the job must fail. A missing scan must never look like zero findings.
  • Report formatting fails: fail, but still try to publish the raw output.
  • Chat message fails: often acceptable to continue, since the ticket or summary carries the information. Mark that step continue-on-error and log a warning.
  • Cleanup step fails: continue.

Use continue-on-error sparingly. Each use is a place where failure becomes invisible.

Alert on the automation itself

A failed security job should tell someone. The simplest pattern is a last step with if: failure() that sends a short message to a team channel. Include the workflow name, repository and a run link. Beware of the trap that the alert path may also be broken, so also run a freshness check that asks when the last successful run happened. See detecting a silently failing scheduled scan and monitoring your security gate's health.

Fail open or fail closed

For a release gate, decide in advance what happens when the scanner is down. Failing closed blocks all releases when the vendor has an outage. Failing open lets unscanned code through. Many teams choose fail closed for production branches with a documented, time limited override, and fail open with a loud warning elsewhere. Write the choice down, because the argument is much worse during an outage. Our post on admission webhook timeouts and failure policy discusses the same tradeoff in Kubernetes.

Try it yourself

Click through it at your own pace, or open it full screen.

Watch what the gate does on a failing check and think about what it should do if the scanner itself were unreachable.

Safeguard provides policies and gates for pull requests. Try the free scan at gold.safeguard.sh/scan.

Quick check

What is the default job timeout?

360 minutes according to GitHub's workflow syntax reference. Set a shorter explicit value.

Should a failed scan fail the whole job?

Yes. A scan that did not run must not be reported as a clean result.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.