SonarSource/sonarqube · error · IllegalArgumentException

Fail to restore Quality profile backup, XML document is not

Error message

Fail to restore Quality profile backup, XML document is not well formed

What it means

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.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileParser.java:150

      rootC.advance(); // <profile>
      if (!ATTRIBUTE_PROFILE.equals(rootC.getLocalName())) {
        throw new IllegalArgumentException("Backup XML is not valid. Root element must be <profile>.");
      }
      SMInputCursor cursor = rootC.childElementCursor();

      while (cursor.getNext() != null) {
        String nodeName = cursor.getLocalName();
        if (CS.equals(ATTRIBUTE_NAME, nodeName)) {
          profileName = StringUtils.trim(cursor.collectDescendantText(false));
        } else if (CS.equals(ATTRIBUTE_LANGUAGE, nodeName)) {
          profileLang = StringUtils.trim(cursor.collectDescendantText(false));
        } else if (CS.equals(ATTRIBUTE_RULES, nodeName)) {
          SMInputCursor rulesCursor = cursor.childElementCursor("rule");
          rules = parseRuleActivations(rulesCursor);
        }
      }
    } catch (XMLStreamException e) {
      throw new IllegalArgumentException("Fail to restore Quality profile backup, XML document is not well formed", e);
    }
    return new ImportedQProfile(profileName, profileLang, rules);
  }

  private static SMInputFactory initStax() {
    XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
    xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
    xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
    // just so it won't try to load DTD in if there's DOCTYPE
    xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
    xmlFactory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
    return new SMInputFactory(xmlFactory);
  }

  private static List<ImportedRule> parseRuleActivations(SMInputCursor rulesCursor) throws XMLStreamException {
    List<ImportedRule> activations = new ArrayList<>();
    Set<RuleKey> activatedKeys = new HashSet<>();
    List<RuleKey> duplicatedKeys = new ArrayList<>();

View on GitHub (pinned to 184c821202)

Solutions

  1. Validate the file with an XML parser locally (xmllint --noout) and fix or re-export it.
  2. Re-export the backup from the source SonarQube server instead of repairing a corrupt file.
  3. Escape XML special characters (&amp;, &lt;) if the file was hand-edited or generated.
  4. Ensure the file is transferred and stored as UTF-8 and complete (compare checksums/sizes).

Example fix

// before
restoreProfile(readBytes("profile.xml")); // 500/400: XML not well formed
// after
Process p = new ProcessBuilder("xmllint", "--noout", "profile.xml").start();
if (p.waitFor() != 0) {
  throw new IllegalStateException("profile.xml is not well-formed XML; re-export it");
}
restoreProfile(readBytes("profile.xml"));
Defensive patterns

Strategy: validation

Validate before calling

// run before upload
int exit = new ProcessBuilder("xmllint", "--noout", backupPath).start().waitFor();
if (exit != 0) throw new IllegalStateException(backupPath + " is not well-formed XML");

Try / catch

try {
  restoreProfile(stream);
} catch (SonarQubeClientException e) {
  if (String.valueOf(e.getMessage()).contains("XML document is not well formed")) {
    LOG.error("re-export or repair the backup; check for truncation and unescaped entities", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

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/cd00c23edb4ef0da. Report an issue: GitHub.