Clean as You Code: Making SonarQube Quality Gates Actually Work
Your SonarQube quality gate fails on legacy code, so the team ignores it. Here is how to scope enforcement to New Code, use branch analysis, and verify the result in CI.
16 Oct 2026, 05:30 UTC

Most SonarQube instances do not fail because the tool is broken. They fail because the quality gate is evaluated against the entire codebase, including years of accumulated legacy debt. When a gate reports thousands of issues on day one, teams learn to click past it. The useful fix is not a bigger cleanup project; it is changing what the gate measures.
The takeaway: SonarQube's "Clean as You Code" model works when you define a stable New Code baseline, attach a Quality Gate that evaluates only that baseline, and verify the verdict through the Web API before wiring it into CI.
New Code turns an infinite backlog into a reviewable diff
SonarQube separates Overall Code from New Code. Overall Code is everything the scanner sees. New Code is a moving window that you define: the previous version, a number of days, or a specific calendar date. Issues, coverage, and duplication metrics are calculated against this window.
This distinction matters because it converts an unmanageable legacy backlog into a bounded, reviewable diff. If you introduce a blocker issue today, it appears under New Code immediately, even if the project has thousands of older issues. Older SonarQube versions called this concept the "leak period"; current documentation uses "New Code," but menu labels and condition names have shifted across releases, so verify the exact wording in your instance.
Set the baseline before you enforce anything. If no New Code period is defined, the first analysis can treat the entire codebase as new code, causing the gate to fail on legacy issues you did not touch.
The Quality Gate is the enforcement point, not the dashboard
A Quality Gate is a named set of pass/fail conditions evaluated for each analysis. The built-in Sonar way gate already blocks new blocker and critical issues and requires a minimum coverage threshold on new code. The gate result is the practical signal your CI pipeline should act on.
One common mistake is gating on unreviewed Security Hotspots. Hotspots are security-sensitive code that needs human review; Vulnerabilities are confirmed problems. Requiring every hotspot to be "fixed" often pushes developers to mark them safe without reading the code. Gate on vulnerabilities, and track hotspot review as a separate workflow.
Branch and pull-request analysis focus the review
Branch and pull-request (PR) analysis report only what changed relative to a base branch. This complements New Code by giving reviewers a focused diff instead of a project-wide report. However, this is an edition-dependent capability, not a Community Edition guarantee. Before promising PR decoration in your pipeline, confirm your license in the instance administration area and test with a real pull request.
A worked example: baseline, gate, and verification
Suppose you have a scratch project and want to enforce that new code stays healthy without failing on legacy files.
- Define New Code. In the project settings, set the New Code definition to Previous version if you tag releases, or Number of days with a small window such as
30. Keep this definition stable; resetting the period or excluding files is the easiest way to game the gate. - Attach a gate. Use the built-in Sonar way gate, or create a custom gate with a condition such as Coverage on New Code is less than 80. Assign it to your project.
- Run the scanner. From your project root, run the analysis. The exact command depends on your build tool, but a generic scanner invocation looks like this:
sonar-scanner \
-Dsonar.projectKey=your-project-key \
-Dsonar.sources=. \
-Dsonar.host.url=http://your-sonarqube-instance:9000 \
-Dsonar.token=your-token
Run this from the directory containing your source code. You need a token with Execute Analysis permission on the project. The scanner uploads the report; it does not modify your source tree.
- Check the verdict. Rather than trusting the project banner alone, query the Web API to see the exact status your CI would act on:
curl -u your-token: \
"http://your-sonarqube-instance:9000/api/qualitygates/project_status?projectKey=your-project-key"
This returns the gate status and the conditions that failed. If coverage fails, verify that your test report paths are correct before assuming a real regression; missing or mislocated coverage files are a common tooling failure.
Trade-offs and limitations
- First-analysis trap. If no New Code baseline exists, the initial scan can mark everything as new code. Set the baseline before attaching the gate.
- Multi-module aggregation. In multi-module builds, the project-level gate can pass while a single module regresses, because conditions aggregate across modules. Inspect per-module measures rather than trusting only the project banner.
- Coverage noise. Coverage conditions can fail because test reports were not generated or were placed in an unexpected directory. Use coverage exclusions deliberately, not as a way to hide untested new code.
- Edition boundaries. Branch and PR analysis are not available in every SonarQube edition. Confirm your license before designing a pipeline around PR comments.
What to do next
Pick one repository. Set New Code to a stable definition—previous version or a fixed date. Attach the Sonar way gate. Run one analysis and query api/qualitygates/project_status to confirm the verdict. Once that loop is reliable, add branch or PR analysis if your edition supports it. The goal is not a clean legacy codebase overnight; it is a gate that fails on a small, fixable diff today instead of an ignored backlog tomorrow.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.