{"record":{"id":"cd00c23edb4ef0da","repo":"SonarSource/sonarqube","slug":"fail-to-restore-quality-profile-backup-xml-docume","errorCode":null,"errorMessage":"Fail to restore Quality profile backup, XML document is not well formed","messagePattern":"Fail to restore Quality profile backup, XML document is not well formed","errorType":"http","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileParser.java","lineNumber":150,"sourceCode":"      rootC.advance(); // <profile>\n      if (!ATTRIBUTE_PROFILE.equals(rootC.getLocalName())) {\n        throw new IllegalArgumentException(\"Backup XML is not valid. Root element must be <profile>.\");\n      }\n      SMInputCursor cursor = rootC.childElementCursor();\n\n      while (cursor.getNext() != null) {\n        String nodeName = cursor.getLocalName();\n        if (CS.equals(ATTRIBUTE_NAME, nodeName)) {\n          profileName = StringUtils.trim(cursor.collectDescendantText(false));\n        } else if (CS.equals(ATTRIBUTE_LANGUAGE, nodeName)) {\n          profileLang = StringUtils.trim(cursor.collectDescendantText(false));\n        } else if (CS.equals(ATTRIBUTE_RULES, nodeName)) {\n          SMInputCursor rulesCursor = cursor.childElementCursor(\"rule\");\n          rules = parseRuleActivations(rulesCursor);\n        }\n      }\n    } catch (XMLStreamException e) {\n      throw new IllegalArgumentException(\"Fail to restore Quality profile backup, XML document is not well formed\", e);\n    }\n    return new ImportedQProfile(profileName, profileLang, rules);\n  }\n\n  private static SMInputFactory initStax() {\n    XMLInputFactory xmlFactory = XMLInputFactory.newInstance();\n    xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);\n    xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);\n    // just so it won't try to load DTD in if there's DOCTYPE\n    xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);\n    xmlFactory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);\n    return new SMInputFactory(xmlFactory);\n  }\n\n  private static List<ImportedRule> parseRuleActivations(SMInputCursor rulesCursor) throws XMLStreamException {\n    List<ImportedRule> activations = new ArrayList<>();\n    Set<RuleKey> activatedKeys = new HashSet<>();\n    List<RuleKey> duplicatedKeys = new ArrayList<>();","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileParser.java#L132-L168","documentation":"QProfileParser.readXml wraps XMLStreamException in IllegalArgumentException with this fixed message when the uploaded backup XML cannot be parsed at all — the document violates XML well-formedness (unbalanced tags, bad entities, encoding problems). The original exception is attached as the cause.","triggerScenarios":"POST api/qualityprofiles/restore with a truncated/corrupted XML file, unescaped '&' or '<' in rule names/parameters, mismatched encodings (file declares UTF-8 but contains other bytes), or an empty file.","commonSituations":"Backups cut short by failed downloads or disk-full exports; templating tools injecting unescaped values into XML; files re-encoded by editors or transfer tools (Windows-1252/ISO-8859-1).","solutions":["Validate the file with an XML parser locally (xmllint --noout) and fix or re-export it.","Re-export the backup from the source SonarQube server instead of repairing a corrupt file.","Escape XML special characters (&amp;, &lt;) if the file was hand-edited or generated.","Ensure the file is transferred and stored as UTF-8 and complete (compare checksums/sizes)."],"exampleFix":"// before\nrestoreProfile(readBytes(\"profile.xml\")); // 500/400: XML not well formed\n// after\nProcess p = new ProcessBuilder(\"xmllint\", \"--noout\", \"profile.xml\").start();\nif (p.waitFor() != 0) {\n  throw new IllegalStateException(\"profile.xml is not well-formed XML; re-export it\");\n}\nrestoreProfile(readBytes(\"profile.xml\"));","handlingStrategy":"validation","validationCode":"// run before upload\nint exit = new ProcessBuilder(\"xmllint\", \"--noout\", backupPath).start().waitFor();\nif (exit != 0) throw new IllegalStateException(backupPath + \" is not well-formed XML\");","typeGuard":null,"tryCatchPattern":"try {\n  restoreProfile(stream);\n} catch (SonarQubeClientException e) {\n  if (String.valueOf(e.getMessage()).contains(\"XML document is not well formed\")) {\n    LOG.error(\"re-export or repair the backup; check for truncation and unescaped entities\", e);\n  }\n  throw e;\n}","preventionTips":["Verify file completeness (size/checksum) after download","Escape & and < when generating XML via templating","Keep backup files UTF-8 end to end"],"tags":["sonarqube","webapi","quality-profile","xml","malformed-input"],"backgroundTag":"json-parse-error","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}