**
This is a bug report**, with a reproducer attached. Three distinct parse failures in sonar-iac
against valid Azure Pipelines YAML, stable across two scanner majors. Five files in our
repository are silently dropped from analysis on every run.
ALM used
Azure DevOps (Azure Repos, dev.azure.com).
CI system used
Azure DevOps Pipelines, Microsoft-hosted Linux agents (ubuntu), via the SonarCloud extension tasks
SonarCloudPrepare / SonarCloudAnalyze / SonarCloudPublish 4.2.5.
Scanner command used
Invoked by the extension task (org/project keys masked). dotnet (“MSBuild”) mode:
/usr/local/bin/dotnet \
/mnt/vss/_work/_tasks/SonarCloudPrepare_<guid>/4.2.5/dotnet-sonar-scanner-msbuild/SonarScanner.MSBuild.dll \
begin /k:<project-key> /o:<org-key>
…
/usr/local/bin/dotnet \
/mnt/vss/_work/_tasks/SonarCloudPrepare_<guid>/4.2.5/dotnet-sonar-scanner-msbuild/SonarScanner.MSBuild.dll \
end
Reported by the scanner as:
SonarScanner for .NET 11.2.1
Using the .NET Core version of the Scanner for .NET
Analysis properties come from a checked-in sonar-project.properties plus a small number of computed
values passed through the task’s extraProperties. Nothing sets any sonar-iac option.
Versions
| Product | SonarQube Cloud (sonarcloud.io), server 8.0.0.101590 |
| Analyzer | iac — IaC Code Quality and Security 2.14.0.22356 (from /api/plugins/installed) |
| Scanner | SonarScanner for .NET 11.2.1 |
| ADO extension tasks | 4.2.5 |
| Java | 21.0.11 Eclipse Adoptium (64-bit), Linux x64 |
Also reproduced under tasks 3.4.3 / SonarScanner for MSBuild 10.3 — identical file set. This is
not a regression in either scanner version, which is why we believe it sits in the analyzer.
Languages of the repository
Analysed quality profiles in the affected run: cs, css, docker, js, json, powershell,
py, shell, ts, web, xml, yaml. The failing files are Azure Pipelines YAML, handled by
the iac sensors (IaC Azure Pipelines Sensor, IaC YAML File Type Classification Sensor).
Project URL
The project is private, so there is no public URL. No PR decoration involved — this reproduces on
both branch and PR analyses.
Error observed
All three are logged as WARN: Cannot parse '<file>' at default verbosity. The underlying message
appears only at DEBUG, and there is no Caused by: clause — it is emitted as its own DEBUG
line immediately before the ParseException stack, with the exception class name inside the
message text. That is why this went undiagnosed on our side for months.
Signature 1 — CommentEvent cannot be cast to NodeEvent (4 files)
WARN: Cannot parse '<file>'
DEBUG: class org.snakeyaml.engine.v2.events.CommentEvent cannot be cast to class org.snakeyaml.engine.v2.events.NodeEvent (org.snakeyaml.engine.v2.events.CommentEvent and org.snakeyaml.engine.v2.events.NodeEvent are in unnamed module of loader org.sonar.classloader.ClassRealm @7b4acdc2)
DEBUG: org.sonar.iac.common.extension.ParseException: Cannot parse '<file>'
at org.sonar.iac.common.extension.ParseException.createGeneralParseException(ParseException.java:40)
at org.sonar.iac.common.extension.ParseException.createGeneralParseException(ParseException.java:35)
at org.sonar.iac.common.extension.ParseException.toParseException(ParseException.java:63)
at org.sonar.iac.common.extension.analyzer.AbstractAnalyzer.parse(AbstractAnalyzer.java:80)
at org.sonar.iac.common.extension.analyzer.SingleFileAnalyzer.lambda$analyseFile$0(SingleFileAnalyzer.java:75)
at org.sonar.iac.common.extension.DurationStatistics.time(DurationStatistics.java:72)
at org.sonar.iac.common.extension.analyzer.SingleFileAnalyzer.analyseFile(SingleFileAnalyzer.java:75)
at org.sonar.iac.common.extension.analyzer.SingleFileAnalyzer.analyseFiles(SingleFileAnalyzer.java:59)
at org.sonar.iac.common.extension.IacSensor.executeIfActive(IacSensor.java:98)
at org.sonar.iac.common.extension.TogglableSensor.execute(TogglableSensor.java:29)
at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:67)
at org.sonar.scanner.sensor.AbstractSensorsExecutor.executeSensors(AbstractSensorsExecutor.java:40)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:44)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:62)
Four Azure Pipelines templates, 245–692 lines each. The attached file is one of them.
Signature 2 — off-by-one, Range [1025, 1025 + 1) out of bounds for length 1025 (1 file)
WARN: Cannot parse '<file>'
DEBUG: Range [1025, 1025 + 1) out of bounds for length 1025
DEBUG: org.sonar.iac.common.extension.ParseException: Cannot parse '<file>'
at org.sonar.iac.common.extension.ParseException.createGeneralParseException(ParseException.java:40)
... identical stack to Signature 1
1025 = 1024 + 1 looks like an internal buffer boundary rather than our content: that file had no
scalar, comment run or line anywhere near 1024 characters (longest line, 251).
Signature 3 — ParseException with no underlying message at all (1 file)
WARN: Cannot parse '<file>'
DEBUG: org.sonar.iac.common.extension.ParseException: Cannot parse '<file>'
at org.sonar.iac.common.extension.ParseException.createGeneralParseException(ParseException.java:40)
... identical stack to Signature 1
No message line is emitted at all. Independently of the parse failure, we think this is a defect on
its own: it makes the whole class unreportable, because there is nothing to quote.
Common frame
All three bottom out at:
org.sonar.iac.common.extension.analyzer.AbstractAnalyzer.parse(AbstractAnalyzer.java:80)
Possibly related
The same files log this shortly before failing. We do not know whether embedded-script parsing and
the YAML event stream interact:
DEBUG: Failed to parse embedded bash content in block "stages.jobs.steps.inputs.inlineScript"
Steps to reproduce
- Add the attached
service-dependencies-redacted.ymlto a repository analysed by SonarQube Cloud,
somewhere insidesonar.sources/sonar.inclusions. - Run an analysis with the
azurepipelines/iacsensors active (default). - Observe
WARN: Cannot parse '<path>'for that file, and note it produces no findings and no
measures. - Re-run with
sonar.verbose=trueto see theDEBUGcause line and the stack above.
The attached file reproduces Signature 1 deterministically — every run, both scanner majors. It is a
redacted copy of a real file from our repository (identifiers scrambled, byte length preserved); we
re-ran analysis against the redacted copy specifically to confirm the redaction did not mask the bug.
What we already ruled out
Please don’t spend time on these — we tested each:
- snakeyaml #1062 (
CommentEventcast on a flow map with a comment after{). Does not
apply: grepping[\{\[]\s*#across all 60 YAML files in the tree returns exactly one hit, and it
is inside a PowerShell string in a file failing with a different signature. - Comment position generally. We scored every comment-attachment shape against all 60 files; the
best predicate still had 42 false positives. There is no comment to “move”. - Azure DevOps template expressions (
${{ }}). A passing file has 94 of them, 42 at key
position; a failing file has none. - File size, line length, emoji, BOM, tabs, CRLF. The passing files lead on every one of those
metrics. - Malformed YAML. All of them parse cleanly under PyYAML (1.1),
eemeli/yaml
(1.2 strict) andjs-yaml. - Scanner/task version. Identical failures on tasks 3.4.3 (scanner 10.3) and 4.2.5
(scanner 11.2.1).
Potential workaround
None that we are willing to take, and we would value your view on this.
Adding the files to sonar.exclusions changes nothing about findings — a file that fails to parse
already produces none. What exclusion does remove is the file from
EnterpriseTextAndSecretsSensor, which reads these same files successfully and is the
highest-value check we point at pipeline YAML. So exclusion is a net loss.
Rewriting the files is not viable either: we cannot verify a speculative rewrite without a full
pipeline run each time, and these files drive our release process. With no predicate that separates
passing from failing files, a rewrite would be guesswork.
So we have left them in scope and accepted a blind spot on five files.
What we would like
-
Confirmation these are analyzer defects rather than something we can fix in our YAML.
-
For Signature 3, the underlying exception surfaced in the log even when its message is null —
independent of whatever causes the parse failure.