Skip to content
Latchkey

pytest-cov "Coverage failure: total ... is less than fail-under" in CI

Your coverage gate (--cov-fail-under / fail_under) failed because measured coverage came in below the threshold. Sometimes coverage genuinely dropped; sometimes subprocess or parallel data was never combined, undercounting it.

What this error means

The test run passes but the step fails with Coverage failure: total of 78% is less than fail-under=85% (exit code 2 from coverage). It can also appear when code runs in subprocesses whose coverage was not collected.

coverage output
Required test coverage of 85% not reached. Total coverage: 78.42%
# or
Coverage failure: total of 78 is less than fail-under=85

Common causes

New code lowered coverage

Added code paths without tests dropped the total below the configured gate. This is the gate working as intended.

Subprocess/parallel coverage not combined

Code that runs in subprocesses or across xdist workers writes separate .coverage.* files. Without coverage combine (and parallel/concurrency config), those lines are missed and the total is understated.

How to fix it

Add tests for the uncovered code

Find what is missing and cover it; let the report point you at the gaps.

Terminal
pytest --cov=app --cov-report=term-missing
# the "Missing" column lists uncovered line ranges

Combine subprocess/parallel coverage

Enable parallel mode and combine the data files before reporting.

pyproject.toml
# pyproject.toml
[tool.coverage.run]
parallel = true
concurrency = ["multiprocessing", "thread"]
# then in CI
coverage combine
coverage report --fail-under=85

How to prevent it

  • Run --cov-report=term-missing so gaps are visible in PRs.
  • Combine coverage from subprocesses/xdist before reporting.
  • Raise the threshold gradually as real coverage improves.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →