SBOMFlow Exit Codes

SBOMFlow uses stable exit codes for CI and operator scripts.

CodeMeaningTypical cause
0SuccessCommand completed, or a release gate was informational/not enforced.
1Enforced release gate failedA manufacturer-selected --fail-on-* policy blocked the run.
2Usage, input, IO, or config errorMissing target directory, malformed config, bad arguments, or unwritable output.
3Init refused / bundle verification failedsbomflow init found an existing sbomflow.yaml without --force, or sbomflow verify-bundle found a tampered bundle / failed signature.
4Structural validation failuresbomflow validate or sbomflow audit found malformed/tampered artifacts.
5Strict warnings-as-errorsanalyze --strict (or --strict=code1,code2) matched one or more scan warnings after artifacts were written.

No subcommand is treated as usage error: sbomflow prints help to stderr and exits 2. Gate failures are distinct from structural validation failures so CI can separate manufacturer policy decisions from broken artifact integrity.

Troubleshooting first-run failures

Common mistakes are designed to self-explain with an actionable message:

  • Missing/file target (exit 2) — "target directory not found … Fix: pass an existing product directory."
  • Malformed or unknown-key config (exit 2) — the parser error plus "Fix: check syntax/keys with sbomflow validate-config <file> or run sbomflow doctor .."
  • Unknown --policy-profile (exit 2) — lists the available shipped presets.
  • Malformed --kev-file/--epss-file/--nvd-file snapshot — never silently ignored: it surfaces a vulnerability_enrichment_error scan warning (and fails under --strict).

sbomflow doctor . is the first stop: it reports Python compatibility, optional extras, the external CycloneDX CLI, and any discoverable config (including parse errors and unknown-key warnings) — all offline.

--strict is opt-in and runs after all artifacts are written, so the evidence pack is always produced; the distinct exit code 5 lets CI fail on warnings without conflating them with a --fail-on-* gate decision (1). Each scan-warning code is registered in the stable catalog (src/sbomflow/warning_catalog.py, version sbomflow-warning-catalog-v1); --strict=<codes> is validated against it.