SonarSource/sonarqube · error · IllegalArgumentException
The quality profile cannot be restored as it contains duplic
Error message
The quality profile cannot be restored as it contains duplicates for the following rules: %s
What it means
QProfileParser.parseRuleActivations detects duplicate rule activations in a profile backup: the same rule key appearing more than once in <rules>. To keep restored profiles deterministic it throws IllegalArgumentException listing the duplicated rule keys.
Source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileParser.java:183
private static List<ImportedRule> parseRuleActivations(SMInputCursor rulesCursor) throws XMLStreamException {
List<ImportedRule> activations = new ArrayList<>();
Set<RuleKey> activatedKeys = new HashSet<>();
List<RuleKey> duplicatedKeys = new ArrayList<>();
while (rulesCursor.getNext() != null) {
SMInputCursor ruleCursor = rulesCursor.childElementCursor();
Map<String, String> parameters = new HashMap<>();
ImportedRule rule = new ImportedRule();
readRule(ruleCursor, parameters, rule);
var ruleKey = rule.getRuleKey();
if (activatedKeys.contains(ruleKey)) {
duplicatedKeys.add(ruleKey);
}
activatedKeys.add(ruleKey);
activations.add(rule);
}
if (!duplicatedKeys.isEmpty()) {
throw new IllegalArgumentException("The quality profile cannot be restored as it contains duplicates for the following rules: " +
duplicatedKeys.stream().map(RuleKey::toString).filter(Objects::nonNull).collect(Collectors.joining(", ")));
}
return activations;
}
private static void readRule(SMInputCursor ruleCursor, Map<String, String> parameters, ImportedRule rule) throws XMLStreamException {
while (ruleCursor.getNext() != null) {
String nodeName = ruleCursor.getLocalName();
if (CS.equals(ATTRIBUTE_REPOSITORY_KEY, nodeName)) {
rule.setRepository(StringUtils.trim(ruleCursor.collectDescendantText(false)));
} else if (CS.equals(ATTRIBUTE_KEY, nodeName)) {
rule.setKey(StringUtils.trim(ruleCursor.collectDescendantText(false)));
} else if (CS.equals(ATTRIBUTE_TEMPLATE_KEY, nodeName)) {
rule.setTemplate(StringUtils.trim(ruleCursor.collectDescendantText(false)));
} else if (CS.equals(ATTRIBUTE_NAME, nodeName)) {
rule.setName(StringUtils.trim(ruleCursor.collectDescendantText(false)));
} else if (CS.equals(ATTRIBUTE_TYPE, nodeName)) {
rule.setType(StringUtils.trim(ruleCursor.collectDescendantText(false)));View on GitHub (pinned to 184c821202)
Solutions
- Deduplicate the <rules> section: keep one <rule> per key, merging parameters as needed.
- Re-export the profile from the source server rather than concatenating exports.
- Pre-validate by parsing rule keys locally and refusing files with duplicates before upload.
- If duplicates carry different parameters, decide which parameters win and edit the XML to a single entry.
Example fix
// before
restoreProfile(concat(exportA, exportB)); // duplicate <rule> keys
// after
Set<String> seen = new HashSet<>();
for (Element rule : ruleElements(doc)) {
String key = rule.getAttribute("key");
if (!seen.add(key)) {
rule.getParentNode().removeChild(rule); // keep first occurrence
}
}
restoreProfile(new ByteArrayInputStream(serialized(doc))); Defensive patterns
Strategy: validation
Validate before calling
Set<String> keys = new HashSet<>();
for (Element rule : doc.getElementsByTagName("rule")) {
if (!keys.add(((Element) rule).getAttribute("key"))) {
throw new IllegalStateException("duplicate rule key in backup: " + ((Element) rule).getAttribute("key"));
}
} Try / catch
try {
restoreProfile(stream);
} catch (SonarQubeClientException e) {
if (String.valueOf(e.getMessage()).contains("contains duplicates for the following rules")) {
LOG.error("deduplicate <rules> entries in the backup before restoring");
}
throw e;
} Prevention
- Never concatenate profile exports; merge rule entries by key instead
- Edit parameters in the existing <rule> entry rather than adding a second one
- Validate backup XML for duplicate rule keys before upload
When it happens
Trigger: POST api/qualityprofiles/restore with a backup XML that contains two <rule> entries with the same key (with or without differing parameters). Merged/concatenated backups from multiple exports; hand-edited files duplicating a rule block.
Common situations: Merging profile exports from different servers that share rules; scripted XML merging that appended instead of replacing; manual edits re-adding a rule to change its parameters instead of editing the existing entry.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Backup XML is not valid. Root element must be <profile>.
- Fail to restore Quality profile backup, XML document is not
- The quality profile cannot be restored as it contains rules
- Source and target profiles are equal: %s
- Unknown severity: %s
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/7d874ec463bc2149.
Report an issue: GitHub.