From c8cf39dcce26a48c9e55bc872f1c71768767639a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Mon, 8 Sep 2025 13:10:17 +0200 Subject: [PATCH] Fix exceptions in index pattern conflict checks (#134231) We already fixed an issue with this in #128362 but apparently another instance of the unnecessary determinization was hiding elsewhere and in its current state throws exceptions starting with Lucene 10 on complext patterns. This change adds the same fix as #128362 and adds a test that would have triggered this. Closes #133652 --- docs/changelog/134231.yaml | 6 ++++++ .../metadata/MetadataIndexTemplateService.java | 8 ++++++-- .../MetadataIndexTemplateServiceTests.java | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 docs/changelog/134231.yaml diff --git a/docs/changelog/134231.yaml b/docs/changelog/134231.yaml new file mode 100644 index 0000000000000..dd0e7f5f84f0d --- /dev/null +++ b/docs/changelog/134231.yaml @@ -0,0 +1,6 @@ +pr: 134231 +summary: Fix unnecessary determinization in index pattern conflict checks +area: Indices APIs +type: bug +issues: + - 133652 diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java index 69dd4359fd764..16a7783d3265b 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateService.java @@ -995,12 +995,16 @@ static Map> findConflictingV2Templates( boolean checkPriority, long priority ) { - Automaton v1automaton = Regex.simpleMatchToAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY)); + // No need to determinize the automaton, as it is only used to check for intersection with another automaton. + // Determinization is avoided because it can fail or become very costly due to state explosion. + Automaton v1automaton = Regex.simpleMatchToNonDeterminizedAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY)); Map> overlappingTemplates = new TreeMap<>(); for (Map.Entry entry : project.templatesV2().entrySet()) { String name = entry.getKey(); ComposableIndexTemplate template = entry.getValue(); - Automaton v2automaton = Regex.simpleMatchToAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY)); + // No need to determinize the automaton, as it is only used to check for intersection with another automaton. + // Determinization is avoided because it can fail or become very costly due to state explosion. + Automaton v2automaton = Regex.simpleMatchToNonDeterminizedAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY)); if (Operations.isEmpty(Operations.intersection(v1automaton, v2automaton)) == false) { if (checkPriority == false || priority == template.priorityOrZero()) { logger.debug( diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java index 9a37cd6dd85b8..64cd2ff45667a 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexTemplateServiceTests.java @@ -2495,6 +2495,23 @@ public void testV2TemplateOverlaps() throws Exception { } } + /** + * test that using complex index patterns doesn't run into a too_complex_to_determinize_exception, + * see https://github.com/elastic/elasticsearch/issues/133652 + */ + public void testFindConflictingTemplates_complex_pattern() throws Exception { + ProjectMetadata initialProject = ProjectMetadata.builder(randomProjectIdOrDefault()).build(); + List complexPattern = new ArrayList<>(); + for (int i = 1; i < 20; i++) { + complexPattern.add("cluster-somenamespace-*-app" + i + "*"); + } + ComposableIndexTemplate template = ComposableIndexTemplate.builder().indexPatterns(complexPattern).build(); + MetadataIndexTemplateService service = getMetadataIndexTemplateService(); + ProjectMetadata project = service.addIndexTemplateV2(initialProject, false, "foo", template); + assertEquals(0, MetadataIndexTemplateService.findConflictingV1Templates(project, "foo", complexPattern).size()); + assertEquals(0, MetadataIndexTemplateService.findConflictingV2Templates(project, "foo", complexPattern).size()); + } + /** * Tests to add two component templates but ignores both with is valid *