SonarSource/sonarqube · error · SarifDeserializationException
SYNTAX
SYNTAX
Error message
Failed to read SARIF report at '%s': %s
What it means
SonarQube's SARIF importer wraps Jackson's JsonParseException into SarifDeserializationException with Category.SYNTAX when the report file at reportPath is not valid JSON (malformed syntax: stray characters, truncation, truncated/unterminated strings or brackets). The message 'Failed to read SARIF report at %s: %s' embeds the path and Jackson's own parse-error description (often with line/column). It is thrown from SarifSerializerImpl.deserialize so callers can classify import failures by category.
Source
Thrown at sonar-core/src/main/java/org/sonar/core/sarif/SarifSerializerImpl.java:88
@Override
public SarifSchema210 deserialize(Path reportPath) {
try {
return mapper
.enable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION)
.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleInstantiationProblem(DeserializationContext ctxt, Class<?> instClass, Object argument, Throwable t) throws IOException {
if (!instClass.equals(SarifSchema210.Version.class)) {
return NOT_HANDLED;
}
throw new UnsupportedSarifVersionException(format(UNSUPPORTED_VERSION_MESSAGE_TEMPLATE, argument), t);
}
})
.readValue(reportPath.toFile(), SarifSchema210.class);
} catch (UnsupportedSarifVersionException e) {
throw new SarifDeserializationException(Category.MAPPING, e.getMessage(), e);
} catch (JsonParseException e) {
throw new SarifDeserializationException(Category.SYNTAX, format(SARIF_REPORT_ERROR, reportPath, e.getMessage()), e);
} catch (JsonMappingException e) {
if (e.getMessage() != null && (e.getMessage().contains("out of range") || e.getMessage().contains("overflow"))) {
throw new SarifDeserializationException(Category.VALUE, format(SARIF_REPORT_ERROR, reportPath, e.getMessage()), e);
}
throw new SarifDeserializationException(Category.MAPPING, format(SARIF_REPORT_ERROR, reportPath, e.getMessage()), e);
} catch (FileNotFoundException e) {
throw new SarifDeserializationException(Category.FILE_NOT_FOUND, format(SARIF_REPORT_ERROR, reportPath, e.getMessage()), e);
} catch (IOException e) {
throw new IllegalStateException(format(SARIF_REPORT_ERROR, reportPath, e.getMessage()), e);
}
}
private static class UnsupportedSarifVersionException extends IOException {
public UnsupportedSarifVersionException(String message, Throwable t) {
super(message, t);
}
}View on GitHub (pinned to 184c821202)
Solutions
- Open the report at the path in the message and validate it with a JSON linter/parser (e.g. `jq . report.sarif`) to find the exact line/column Jackson reports
- Re-export or re-download the SARIF report from the producing tool; verify the download completed (compare file size/checksum)
- Verify the path passed to deserialize()/sonar.sarifReportPaths points to the actual SARIF JSON file, not a log, HTML page, or directory listing
- Ensure the file is UTF-8 encoded without BOM and was not truncated by the transfer
Example fix
// before
SarifSchema210 sarif = sarifSerializer.deserialize(reportPath); // throws SYNTAX on corrupt file
// after
byte[] bytes = java.nio.file.Files.readAllBytes(reportPath);
try (var parser = new com.fasterxml.jackson.core.JsonFactory().createParser(bytes)) {
while (parser.nextToken() != null) { } // fail fast with Jackson's line/column if invalid
}
SarifSchema210 sarif = sarifSerializer.deserialize(reportPath); Defensive patterns
Strategy: validation
Validate before calling
boolean isValidJsonFile(Path p) throws IOException {
if (!Files.isRegularFile(p)) return false;
try (com.fasterxml.jackson.core.JsonParser parser = new com.fasterxml.jackson.core.JsonFactory()
.createParser(Files.newBufferedReader(p, StandardCharsets.UTF_8))) {
while (parser.nextToken() != null) { }
return true;
} catch (com.fasterxml.jackson.core.JsonParseException e) {
return false;
}
} Type guard
boolean isReadableSarif(Path p) {
return Files.isRegularFile(p) && Files.size(p) > 0
&& p.getFileName().toString().matches("(?i).*\\.sarif(json)?$");
} Try / catch
try {
SarifSchema210 sarif = serializer.deserialize(reportPath);
} catch (SarifDeserializationException e) {
if (e.getCategory() == Category.SYNTAX) {
LOG.error("SARIF report is not valid JSON: {}", reportPath); // skip or re-export
} else throw e;
} Prevention
- Validate generated SARIF output with the official SARIF 2.1.0 schema in your pipeline before import
- Validate the JSON parses (jq or a JSON parser) as part of report generation
- Avoid hand-editing SARIF files; always re-export from the producing tool
- Check for truncated transfers by comparing file size/checksum after download
When it happens
Trigger: Calling SarifSerializer.deserialize(Path) (directly or via SARIF report import in SonarQube) on a file whose content is not syntactically valid JSON — e.g. an HTML error page saved as .sarif, a truncated download, a file containing BOM/prose, or an empty file that Jackson reports as 'No content to map due to end-of-input'.
Common situations: CI artifact upload corrupted or truncated the SARIF file; a tool wrote a non-JSON log to the SARIF path; user pointed sonar.sarifReportPaths at the wrong file; file downloaded via HTTP where the server returned an error page with 200; file encoding issues (UTF-16 SARIF read as UTF-8).
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/5bfc2762dfe70185.
Report an issue: GitHub.