subprocess.CalledProcessError
PythonERRORNotableRuntime ErrorHIGH confidence

Called process returned non-zero exit code

Production Risk

Always capture and log stderr; never use shell=True with untrusted input.

What this means

Raised by subprocess.check_call() and subprocess.check_output() when the child process returns a non-zero exit code. Contains the exit code, command, and stderr output.

Why it happens
  1. 1subprocess.run(..., check=True) and the command fails
  2. 2subprocess.check_output() on a command that returns non-zero
  3. 3The external command encounters an error (missing file, wrong arguments, etc.)
How to reproduce

Running a command that fails with check=True.

trigger — this will error
trigger — this will error
import subprocess
subprocess.run(['ls', '/nonexistent'], check=True, capture_output=True)

expected output

subprocess.CalledProcessError: Command '['ls', '/nonexistent']' returned non-zero exit status 2

Fix

Catch CalledProcessError and inspect stderr

WHEN Running external commands that might fail

Catch CalledProcessError and inspect stderr
import subprocess

try:
    result = subprocess.run(
        ['mycommand', 'arg'],
        check=True,
        capture_output=True,
        text=True
    )
    print(result.stdout)
except subprocess.CalledProcessError as e:
    print(f"Command failed with exit {e.returncode}", file=sys.stderr)
    print(f"stderr: {e.stderr}", file=sys.stderr)
    raise

Why this works

e.returncode, e.stdout, and e.stderr contain the full context of the failure.

Code examples
Triggerpython
import subprocess
subprocess.run(["ls", "/nonexistent"], check=True)  # CalledProcessError
Handle with try/exceptpython
import subprocess
try:
    subprocess.run(cmd, check=True, capture_output=True)
except subprocess.CalledProcessError as e:
    print(f"Exit {e.returncode}: {e.stderr.decode()}")
Avoid with returncode checkpython
result = subprocess.run(cmd, capture_output=True)
if result.returncode != 0:
    print(f"Command failed: {result.stderr.decode()}")
What not to do

Use shell=True with user input

shell=True passes the command to /bin/sh — user input can inject arbitrary shell commands (shell injection vulnerability).

Sources
Official documentation ↗

Python Docs — subprocess module

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

← All Python errors