Sonarqube intermittent failure to detect issues

  • Sonarqube Server Developer Edition v2026.4 (125744)
  • Devops Server
  • Pull request decoration, quality gate pr merge blocking
  • Azure devops pipeline agent build integration

Issue:

Sonarqube only detects issues on some pipeline builds, on some pipeline builds issues are detected, on others, issues are not detected.
When issues are not detected, reports: “0 issues, quality gate passed” (like there are no issues, only there are definitely issues still present on changed lines of code)

Once the PR (with outstanding undetected issues) is merged, the issues do usually appear in the main branch, but they are unassigned!

Another thing is the analysis graph which jumps up and down an unreasonable ammount (the code changes alone do not account for this)

The issues coincide with a few changes (but cant be exact as they are intermittent):

  • Update to devops server
  • addition of a git submodule in the codebase
  • change to it infrastructue

Another thing i noticed is this, it only shows up on the main/master branch (not on any PR branch build!) and it only shows up intermittently :

Screenshot 2026-09-09 142335

I have compared the log outputs from both a successful scan that detected issues, and a scan that did not find issues (that is should have detected), i saw no change.

Apologies for sparse information, i dont have too much time to create this post and dont want to share anything im not supposed to

Edit: after a little look at other posts this seems to be related: Issues in new code not detected on branch - SonarQube Server / Community Build - Sonar Community

Hey @Rory, welcome to the Community!

Do you have debug-level scanner logs from both a “good” and a “bad” scan? It would be really interesting to compare debug-level logs to see if both runs are seeing the same files and running the analyzers correctly on them. We can get an approximation of this by having a look at the “Lines of code” metric in the Activity tab (where you saw the Issue count jumping up and down). What we need to understand is if the fluctuation in issues is caused by a fluctuation in the files/lines of code analyzed, or if the analyzed code stays reasonably stable.

Another place where you could look for hints is in the projects’s Background tasks > 3 dots next to a background task > Show scanner context. This will show you the full configuration that was used for a given scanner run. If you can find a good and a bad scan and correlate them with their corresponding background tasks, perhaps you can spot if the difference in issues found is caused by a difference in configuration. To correlate a scan run with its background task, you can check the logs: at the very end, upon submitting the results to the server, it typically prints the background task ID.

Hi @andres,

Just focusing on the request for the lines of code metric: It seems that the “Lines to cover” is the fluctuating issue. There are some big jumps in the Lines which are expected:

  • first one was changing the build type used for the CI build
  • second one was accidentally adding the thirdparty dependencies to the scan
  • third one was restoring the sonar exclusions to ignore the thirdparty folder

Same metrics with the Issues on the bottom graph

Thanks for the advice, i will look into the other suggestions for things like logs if i can find some time to do so.

Thanks - Rory

Just adding a more zoomed in picture of the “lines to cover”

Hey @Rory, thanks for checking that. “Lines to cover” is indeed a good measure to check because it typically corresponds with main code, which is where most issues are raised. It’s interesting to see that the pattern doesn’t strictly correlate with those 3 main events you outlined, instead it correlates with the fluctuations in issues. So it could totally be the case that the fluctuation in issues is caused by a fluctuation in lines/files analyzed.

I suggest you start collecting debug-level scanner logs and, whenever you experience another fluctuation, compare the logs and also perhaps check out the scanner context for both runs.

We could help check out debug-level logs, there might be some technical details in them for us. If you manage to get debug logs for 2 very different runs, let me know. We may ask you to share them via private message.

Hey @andres,
I enabled debug level logs in the SQ administration page (not sure if this is exactly what you meant)

I have found 2 runs, 1 that worked and one that didnt. I have saved the Devops Pipelines logs.

Please advise if i have enabled the wrong logging, or please assist with submitting the logs privately.

Much appreciated - Rory

Hi @Rory, what you did enabled debug-level server-side logs. What we need is debug logs from the Scanner in your CI, which is enabled with a flag passed to the Scanner command. The exact way to do it might depend on how you are running the scanner but the main ways to do it are either:

  • Pass -X to the scanner command, or
  • Set the sonar.verbose=true property, either in a sonar-project.properties file, or via command line like -Dsonar.verbose=true.

Hi @andres
I have finally collected some debug level scanner logs! Currently just working on removing any sensitive information.

Please let me know how to send the logs over,
Thanks - Rory

Hi @Rory,

I had a quick first look at the logs. Here are some interesting points:

The two analyses do not seem to analyze the same stuff, if you search for the following strings in both logs, you’ll see different numbers:

  • Number of compilation units in the provided Compilation Database (949 vs 586)
  • Number of remaining compilation units to be analyzed (513 vs 340)
  • compilation units were fully analyzed (561 vs 375)

So I think that the issue is not in the analysis itself, but in the way the compilation database is created.

The log tells it is generated by the build wrapper. One classical hypothesis is that it is based on incremental build instead of a full build, which lead to an incomplete compilation database, and therefore an incomplete analysis.

We would need to see the compilation database files and to know how they are generated if further investigation is needed.

Thank you!

Thanks for the insight @JolyLoic,

From your insight i have some ideas about what could be causing issues:

For context a full bulid always takes place, but:

  1. Our build requires 2 build steps, firstly building win32, then building x64 in a separate build. This is because some of the build dependencies are not correctly set (the x64 build will fail unless the win32 build has already been ran). The same build wrapper out dir is used for both builds (i havent a clue if this will cause issues). This is done sequentially, but MS build is set to build in parallel- as i type this i realise that this is likely the issue, i will update the pipeline to see if i get some more consistent builds.

Could you link me to any relevant documentation?

In terms of how the build wrapper is ran, i hope this snippet from the Azure DevOps build pipeline provides some context, if not i could work on finding some compilation database files:

All the best - Rory

Edit: Just adding this image for context on some variables in the previous image

It does sound like the root cause of your issue. What I would do:

  • If the code in win32 is just a subset of the code in x64, don’t generate a build wrapper for it, focus on the x64 bits only.
  • Otherwise, you want a single build wrapper that is the combination of both. I would create a script that runs both builds, and wrap the build wrapper around this script, instead of wrapping it directly around MsBuild.

Hope this helps!

Hi @JolyLoic,
Just to update about the msbuild parallel build, after setting it to sequential im now seeing the same number of compilation units in both runs:

Run 1:

2026-10-23T13:13:23.3979722Z 14:13:23.320 INFO: 737 compilation units were fully analyzed
2026-10-23T13:13:23.3980093Z 14:13:23.320 INFO: 0 compilation units were partially analyzed: 0 stopped on Config, 0 stopped on Parsing, 0 stopped on AST, 0 stopped on Symbolic Execution, and 0 stopped on Symbolic Execution with Parsing Error

Run 2:

2026-10-22T18:10:33.5625504Z 19:10:33.305 INFO: 737 compilation units were fully analyzed
2026-10-22T18:10:33.5625805Z 19:10:33.305 INFO: 0 compilation units were partially analyzed: 0 stopped on Config, 0 stopped on Parsing, 0 stopped on AST, 0 stopped on Symbolic Execution, and 0 stopped on Symbolic Execution with Parsing Error

In terms of making a wrapper to wrap both msbuild steps in the build wrapper, not sure how to do this, is there any documentation on the buildwrapper?

FYI just to clarify about what exactly i changed on MSBuild:
Removing the -m option is the fix (but introduces the issue of the pipeline taking > 2 hours…)

All the best - Rory

Hi @Rory,

I am slightly surprised the -m option is doing the trick. The way I understand it, it should not solve the issue. But I also see that you also use the -nr:true option, and I wonder if t a combination of both is what creates the effect.

Could you please ruin 2 more experiments:

  • Only keep the first MsBuild invocation. How many files are analyzed? Are they a subset of the files analyzed when having both invocations?
  • Restore both invocations, but this time with -nr:false.

The build wrapper will monitor all processes that are children of the main process (in your case MsBuild) and look for processes that look like compiler invocation. When you are reusing a node, some compilers will be triggered by the already launched node, and will therefore be invisible to the build wrapper.

As you can read in our doc:

Specifics of using build-wrapper with MSBuild

Instead of starting new nodes when building your code, MsBuild can reuse previously launched build nodes. In that case, Build Wrapper cannot monitor files compiled on these nodes. Therefore, we advise turning off this feature using the nodeReuse:False command-line option.

Finally, what I had in mind for the wrapper was something like this (this is untested pseudo code):
Create a BuildBothPlatforms.cmd file, with a content that looks like this:

MsBuild.exe %* -p:Platform=x86
MsBuild.exe %* -p:Platform=x64

Then, in your pipeline, replace the two lines with:

"$(buildWrapperExe)" --out-dir $(buildwrapperoutdir) BuildBothPlatforms.cmd $(You conytinue to pass all variables except the -p:Platform)

That way, a single build wrapper will wrap the full tree of processes for both MsBuild invocations.

Is it clearer now?

(by the way, copying text instead of pasting screenshots makes it easier for us to give a detailed answer)