SonarSource/sonarqube · error · TemplateMatchingKeyException
The " " key matches multiple permission templates: . A…
Error message
The "{0}" key matches multiple permission templates: {1}. A system administrator must update these templates so that only one of them matches the key. What it means
Permission templates can declare key patterns (project key regexes). When a component key matches more than one template, SonarQube cannot decide which applies, so PermissionTemplateService.checkAtMostOneMatchForComponentKey (invoked via findTemplate) throws this TemplateMatchingKeyException listing the conflicting template names.
Solutions
- Edit the conflicting templates' project key patterns so exactly one matches the key (as the message says, an administrator must do this).
- Remove or narrow any catch-all '.*' template that overlaps specific templates.
- List templates (api/permissions/templates) and check their patterns to identify the overlap.
Example fix
// before template A pattern: .* | template B pattern: ^my-project$ // after template A pattern: ^other-.*$ | template B pattern: ^my-project$
Defensive patterns
Strategy: validation
Validate before calling
// count matches before lookup
long matches = templates.stream()
.filter(t -> t.getProjectKeyPattern().matcher(componentKey).matches())
.count();
if (matches > 1) throw new IllegalStateException("Key matches " + matches + " templates"); Try / catch
try { PermissionTemplateDto tpl = service.findTemplate(db, componentKey); } catch (TemplateMatchingKeyException e) { log.error("Fix overlapping template patterns: {}", e.getMessage()); } Prevention
- Review project key patterns for overlap after any template edit or import.
- Avoid broad catch-all patterns like '.*' alongside specific ones.
When it happens
Trigger: findTemplate is called for a component key and multiple permission templates have patterns matching that key, e.g. two templates both matching 'org:repo' or overlapping regexes like '.*' and '^org:.*'.
Common situations: A catch-all template ('.*') left in place alongside specific templates; duplicated templates after import/restore; pattern edits that broaden a template's regex over existing ones.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Address in property is not a valid address
- allowAllGroups can only be enabled when Auto-provisioning…
- allowAllGroups cannot be enabled when the GitLab URL is…
- allowedGroups cannot be empty when Auto-provisioning is…
- At least one Elasticsearch host is required
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/0ab94e3984440c10.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java:235
case ComponentQualifiers.APP:
String appDefaultTemplateUuid = resolvedDefaultTemplates.getApplication().orElseThrow(
() -> new IllegalStateException("Failed to find default template for applications"));
return dbClient.permissionTemplateDao().selectByUuid(dbSession, appDefaultTemplateUuid);
default:
throw new IllegalArgumentException(format("Qualifier '%s' is not supported", qualifier));
}
}
private static void checkAtMostOneMatchForComponentKey(String componentKey, List<PermissionTemplateDto> matchingTemplates) {
if (matchingTemplates.size() > 1) {
StringBuilder templatesNames = new StringBuilder();
for (Iterator<PermissionTemplateDto> it = matchingTemplates.iterator(); it.hasNext();) {
templatesNames.append("\"").append(it.next().getName()).append("\"");
if (it.hasNext()) {
templatesNames.append(", ");
}
}
throw new TemplateMatchingKeyException(MessageFormat.format(
"The \"{0}\" key matches multiple permission templates: {1}."
+ " A system administrator must update these templates so that only one of them matches the key.",
componentKey,
templatesNames.toString()));
}
}
}
View on GitHub (pinned to 184c821202)