Join our Newsletter — 33% off our NHI Course

Why does SonarQube show 0% coverage when tests pass?

Because the scanner only reports what it can find in a valid coverage report. If the report is missing, misformatted, produced too late, or pointed at the wrong path, tests can pass while SonarQube sees no usable evidence. The failure is usually in the pipeline handoff, not in test execution itself.

Why SonarQube can report 0% coverage even when tests pass

SonarQube does not measure test success directly, it consumes coverage evidence that a build step must generate and place where the scanner expects it. If tests run but the coverage file is missing, unreadable, empty, or written to the wrong location, SonarQube can only report zero coverage because it has no valid data to import.

The practical distinction is between test execution and report ingestion. A green test run proves the test suite passed; it does not prove the scanner received a usable coverage report. That gap is usually caused by pipeline sequencing, file path resolution, report format mismatch, or language-specific tooling configuration rather than by SonarQube itself.

Coverage reporting is also language and build-tool dependent. For example, the scanner may need a JaCoCo XML report, LCOV file, or another supported format, and the report must exist at scan time with the exact path configured. If the report is produced after analysis, excluded by the workspace layout, or generated in a container that is not mounted into the scanner environment, SonarQube has nothing to index.

What usually breaks in the pipeline handoff

The most common failure is a broken handoff between the test job and the analysis job. A CI pipeline can execute tests successfully, then run the SonarQube scan in a later step that no longer has access to the coverage artifact. In that case the coverage is not “lost”, it was never visible to the scanner in the first place.

Path mistakes are just as common. Relative paths, multi-module builds, nonstandard output directories, and containerised runners can all point the scanner at the wrong place. A report may exist on disk, but if the configured property does not resolve to that exact file in the scan workspace, coverage stays at 0%.

Report format problems create the same symptom. A file can be present yet still unusable if the generator output is incompatible with the language plugin, truncated, stale, or malformed. The scanner imports only valid coverage evidence, so a file that looks correct to a human may still be ignored if it is not in the expected schema or encoding.

How to verify the scanner is seeing the right evidence

Start by validating the report itself before you troubleshoot SonarQube. Confirm that the coverage tool produced the expected file, that the file contains real execution data, and that the path in the SonarQube configuration matches the file location in the scan environment. If the report is created in one job and scanned in another, verify the artifact is persisted across that boundary.

Then check the analysis logs for import messages. SonarQube usually tells you whether it found a report, which path it used, and whether it skipped the file. Those log lines are often the fastest way to distinguish “tests ran” from “scanner had no evidence”.

It also helps to inspect the build order. Coverage generation must happen before SonarQube analysis, not after it. If the scan runs too early, it can complete successfully and still report 0% because the report did not exist at the moment of import.

Risk and Threat Considerations

Coverage failures create a blind spot that can hide test gaps, broken instrumentation, or a misconfigured pipeline even when every test is green. The risk is not only a misleading metric, it is a false sense of quality assurance that can let untested code advance through delivery.

Failure mechanism: the analysis step cannot validate code coverage unless the correct report is produced, persisted, and mapped into the scanner’s working path before import. Any break in generation, transport, format compatibility, or timing results in a zero-value report.

Impact: teams may ship code believing test depth is better than it really is, quality gates can become unreliable, and regression visibility can drop across branches or modules.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP ASVS, CIS Controls v8, NIST SP 800-53 Rev 5 and OWASP SAMM set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
OWASP ASVS V16 — Security Logging and Error Handling Coverage import failures need clear analysis logs and traceable error handling.
Recommendation — Check analysis logs and error paths so missing coverage imports are visible immediately.
CIS Controls v8 CIS-8 — Audit Log Management Build and analysis logs are the primary evidence for why coverage was not imported.
Recommendation — Retain scanner and CI logs that prove whether the report was found and ingested.
NIST SP 800-53 Rev 5 AU-3 — Content of Audit Records Coverage analysis depends on sufficient records to show report creation and import conditions.
CM-3 — Configuration Change Control Wrong paths and sequencing are configuration issues that drive false zero coverage.
Recommendation — Ensure pipeline logs capture report generation, path, and import outcomes. Control scan configuration and pipeline sequencing so the coverage artifact is reachable at analysis time.
OWASP SAMM IVM — Implementation Verification Coverage reporting is part of verifying that tests and instrumentation actually produced usable evidence.
Recommendation — Verify the build produces and exposes the intended coverage artifact before relying on the metric.

Practitioner Guidance

What to verify: confirm the coverage file exists in the same workspace the scanner uses, contains fresh data from the latest test run, and matches the supported report format for that language plugin. Treat a successful test job as insufficient evidence until the coverage artifact is proven visible to SonarQube.

Decision rule: if tests pass but coverage is 0%, debug the artifact path and pipeline order before changing tests themselves. If the report is present but still ignored, focus on format compatibility, module mapping, and whether the scan ran in the same environment that produced the file.

Practitioner takeaway: zero coverage usually means “no usable report reached the scanner”, not “the tests did not execute”, so the fastest fix is to prove the report’s existence, path, format, and timing end to end.