Safeguard
Developer Tools•

Safeguard CLI exit codes: what 0, 1 and 2 mean in a script

What the Safeguard CLI scan and detect commands return on exit, why a clean exit code is not a clean scan, and how to branch on 0, 1 and 2 in a script.

Safeguard Security Team
3 min read

For the Safeguard CLI scan command, exit code 0 means the scan ran, whether or not it found anything. Exit code 1 means the command failed. Exit code 2 means results were written but the vulnerability matching step did not run. Findings do not change the exit code, so gating takes extra work.

The documented codes

The usage and CI pages list these for the scan command:

  • 0: the scan ran, regardless of findings
  • 1: the command failed
  • 2: results were written, but the vulnerability scan did not run

The detect command, which looks for secrets and misconfigurations, also returns 0 when the scan ran regardless of findings. It returns non-zero when the command itself fails, for example with an invalid detection type.

That surprises people who expect a scanner to fail the build when it finds something. This one reports and leaves the decision to you.

Why exit code 2 matters

Code 2 is the one to handle on purpose. Your SBOM got written, so the folder looks populated, but the vulnerability step did not run. If your script only checks for code 1, it will treat a half-finished scan as a pass.

A safe pattern:

safeguard scan --dir . --output results
rc=$?
if [ "$rc" -eq 2 ]; then
  echo "Vulnerability scan did not run. Treat as failed." >&2
  exit 1
elif [ "$rc" -ne 0 ]; then
  exit "$rc"
fi

Treat anything other than a clean 0 as a stop, and decide separately what to do about findings.

Gating on findings

The docs say the CLI has no severity threshold flag for scan and that enforcement happens through platform policies and gates. If you want a local gate, read the output file yourself. A short jq check on the grype style file can fail the step when a critical match appears. The next post in this series walks through it.

Other commands you may script

Two more behaviours worth knowing:

  • The doctor command checks your environment, sign-in, tools and policy. Its exit code is 0 whenever the checks ran, so read its output, not its status.
  • The config show command exits non-zero if nothing has been configured yet, which is a handy first line in a setup script.

Help text for the code-scan command in the CLI build we checked says it exits with code 1 when critical or high severity issues are found, and also when any file could not be scanned. Behaviour can differ between builds, so run the help for your installed version before relying on it.

Make the code visible in logs

Print the code you got, and the command that produced it. When a pipeline fails at two in the morning, a line such as "scan exited 2" saves a lot of guessing.

Quick check

Will a scan with critical findings fail my pipeline automatically?

Not through the exit code. The scan command returns 0 when it ran, whatever it found. Add a check on the output file, or enforce rules with platform gates.

What should a script do on exit code 2?

Fail the step. The SBOM exists but vulnerability matching did not run, so the result is incomplete and should not be reported as clean.

You can try the scanning step without installing anything using the free scan at gold.safeguard.sh/scan.

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.