pipefail
BashERRORNotableScriptingHIGH confidence

Pipeline failed (set -o pipefail)

Production Risk

Silent pipeline failures are a common bug; always use set -o pipefail in production scripts.

What this means

`set -o pipefail` changes pipeline exit code semantics: without it, a pipeline returns the exit code of the last command only. With it, a pipeline fails if any command in it fails — catching silent failures in the middle of a pipeline.

Why it happens
  1. 1Any command in a pipeline returns non-zero when set -o pipefail is active
  2. 2An intermediate command silently fails while the final command succeeds
How to reproduce

A middle command fails in a pipeline without pipefail being noticed.

trigger — this will error
trigger — this will error
#!/bin/bash
# Without pipefail — failure is silently hidden
false | true
echo "Without pipefail: $?"   # → 0 (wrong!)

set -o pipefail
false | true
echo "With pipefail: $?"      # → 1 (correct)

expected output

Without pipefail: 0
With pipefail: 1

Fix 1

Enable pipefail in all production scripts

WHEN Writing scripts that use pipelines

Enable pipefail in all production scripts
#!/bin/bash
set -euo pipefail  # errexit + nounset + pipefail

# Now pipeline failures are caught:
generate_data | process_data | upload_data

Why this works

set -euo pipefail is the recommended "safe mode" for bash scripts; it catches most silent failure modes.

Fix 2

Check PIPESTATUS for individual pipeline exit codes

WHEN Needing to know which command in the pipeline failed

Check PIPESTATUS for individual pipeline exit codes
#!/bin/bash
set -o pipefail
cmd1 | cmd2 | cmd3
status=("${PIPESTATUS[@]}")
echo "cmd1 exit: ${status[0]}"
echo "cmd2 exit: ${status[1]}"
echo "cmd3 exit: ${status[2]}"

Why this works

PIPESTATUS is an array holding the exit codes of each command in the most recent pipeline.

What not to do

✕ Rely on pipeline exit codes without pipefail

Without pipefail, a pipeline can silently discard data from failed middle stages while reporting success.

Sources

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Bash errors