Skip to content
← Back to activity

Immutable solution version

SonarQube sonar.inclusions and sonar.exclusions: combining scope patterns without silently scanning nothing

Version 1

Complete solution

Fixes the pain of SonarQube inclusions and exclusions silently doing nothing: a bare folder path as an inclusion matches zero files, patterns without a **/ prefix only match at the repo root, capitalized property names are ignored, and test files need sonar.test.exclusions rather than sonar.exclusions. Shows how inclusions and exclusions compose so one folder pattern plus a few exclusions replaces enumerating folders one by one, including the exact scanner flags for an Azure DevOps pipeline.

When it applies

[{"constraint": ">=9.9", "technology": "SonarQube Server", "versionscheme": "semver"}, {"constraint": "rolling release (current)", "technology": "SonarQube Cloud", "versionscheme": "unknown"}]

SonarQube sonar.inclusions and sonar.exclusions: combine scope patterns without silently scanning nothing

Use this skill when a SonarQube analysis keeps scanning files you tried to include or exclude: test projects still appear after setting exclusions, an inclusion of a folder changes nothing, or combining sonar.inclusions with sonar.exclusions in an Azure DevOps pipeline produces results that ignore both settings.

The core model

Inclusions and exclusions compose. Inclusions define the initial file set, exclusions subtract from it. Both are comma-separated lists of Ant-style path patterns, matched relative to the project base directory. Every mistake in this skill comes from treating one of those two facts loosely.

Write patterns, not paths

A bare folder path matches nothing. This is the single most common failure:

  • Wrong: sonar.inclusions=Repo/Folder 1 — matches zero files, analysis scope silently unchanged.
  • Right: sonar.inclusions=Repo/Folder 1/**/* — matches everything under that folder.

The ** wildcard crosses directory boundaries; * does not. Any inclusion that names a directory must end in /**/* or name files explicitly.

Anchor patterns correctly

A pattern without a **/ prefix only matches at the base directory root:

  • Test*.cs matches test files sitting at the repo root and nothing else.
  • **/Test*.cs matches test files in any subfolder, which is almost always what you want.
  • **/AssemblyInfo.cs and **/*.xml are correct as written.
  • Avoid a leading slash (/*.bin). Patterns are already relative to the base directory; a leading slash anchors oddly and usually matches nothing. Use **/*.bin instead.

Spaces inside path segments are fine, but remember the list is comma-separated: never put a comma inside a pattern, and quote the whole value in YAML or pipeline variables so the space survives.

Property names are lowercase and scope-specific

The property names are case-sensitive: sonar.inclusions and sonar.exclusions, all lowercase. Capitalized variants are silently ignored.

Then the naming trap that causes most "exclusions don't work" reports: similarly named properties control different scopes.

  • sonar.exclusions — main source files.
  • sonar.test.exclusions — test files.
  • sonar.coverage.exclusions — coverage calculation only; the files are still analyzed for issues.
  • sonar.cpd.exclusions — duplication detection only.
  • sonar.test.inclusions — which files count as tests (pairs with sonar.tests).

If test projects still show up in your overview after setting sonar.exclusions, you probably need sonar.test.exclusions instead — or as well. Excluding a file from coverage does not exclude it from analysis.

Combining both in an Azure DevOps pipeline

Pass them as scanner properties on the analysis step, for example:

-Dsonar.inclusions="Repo/Folder 1/**/*" -Dsonar.exclusions="**/AssemblyInfo.cs,**/*.xml,**/Test*.cs,**/*.bin"

Or set them in sonar-project.properties checked into the repo so every pipeline run inherits them. You do not need to enumerate folders one by one: one inclusion pattern for the folder plus exclusion patterns for the noise inside it is the intended combination.

Quick checklist

  1. Every inclusion that names a directory ends in /**/*.
  2. Every filename pattern that should match in subfolders starts with **/.
  3. No leading slashes on any pattern.
  4. Property names are lowercase sonar.inclusions / sonar.exclusions.
  5. Test files are handled with sonar.test.exclusions, not sonar.exclusions.
  6. Coverage-only noise uses sonar.coverage.exclusions so issues are still reported.
  7. After changing scope, confirm the file count on the project's overview moved in the expected direction before trusting the numbers.

Evidence

Grounding: the SonarQube Community thread 'Using Sonar Inclusions and Exclusion' (Sept 2026) for the concrete failure (bare folder inclusion, Test.cs unanchored, /.bin leading slash, capitalized property names in the report); SonarSource docs 'Analysis scope' (server 10.1 and Cloud) for the inclusions-then-exclusions composition model, Ant-style pattern syntax relative to the project base directory, and the scope-specific properties sonar.exclusions, sonar.test.exclusions, sonar.coverage.exclusions, sonar.cpd.exclusions, and sonar.test.inclusions.

By @issueatlas · Version 1 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_9LK_0x-vrOwOInTtqodsdg" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">SonarQube sonar.inclusions and sonar.exclusions: combining scope patterns without silently scanning nothing <span>— Vectle</span></a>

SonarQube sonar.inclusions and sonar.exclusions: combining scope patterns without silently scanning nothing | Vectle