From e4c9d3d033c240f8a0ab253c411ad5b870283b6e Mon Sep 17 00:00:00 2001 From: Matteo Mazzola Date: Mon, 1 Dec 2025 16:12:24 +0000 Subject: [PATCH 1/2] Improved validation message for unknown archived settings (#138810) (cherry picked from commit 074dc72592b9242637cf280768ce23d832730510) # Conflicts: # server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt --- .../elasticsearch/common/ReferenceDocs.java | 1 + .../settings/AbstractScopedSettings.java | 62 +++++++++++++------ .../common/reference-docs-links.txt | 3 +- .../common/settings/ScopedSettingsTests.java | 17 +++++ 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java b/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java index 912f8c8fbe88c..de4c7693077b3 100644 --- a/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java +++ b/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java @@ -85,6 +85,7 @@ public enum ReferenceDocs { SECURE_SETTINGS, CLUSTER_SHARD_LIMIT, DELETE_INDEX_BLOCK, + ARCHIVED_SETTINGS, // this comment keeps the ';' on the next line so every entry above has a trailing ',' which makes the diff for adding new links cleaner ; diff --git a/server/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java index 604f281a82310..a31ca1820b095 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java @@ -14,6 +14,8 @@ import org.apache.lucene.search.spell.LevenshteinDistance; import org.apache.lucene.util.CollectionUtil; import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.common.ReferenceDocs; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.util.Maps; import org.elasticsearch.common.util.set.Sets; @@ -543,29 +545,40 @@ void validate(final String key, final Settings settings, final boolean validateV void validate(final String key, final Settings settings, final boolean validateValue, final boolean validateInternalOrPrivateIndex) { Setting setting = getRaw(key); if (setting == null) { - LevenshteinDistance ld = new LevenshteinDistance(); - List> scoredKeys = new ArrayList<>(); - for (String k : this.keySettings.keySet()) { - float distance = ld.getDistance(key, k); - if (distance > 0.7f) { - scoredKeys.add(new Tuple<>(distance, k)); - } - } - CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1())); - String msgPrefix = "unknown setting"; SecureSettings secureSettings = settings.getSecureSettings(); - if (secureSettings != null && settings.getSecureSettings().getSettingNames().contains(key)) { - msgPrefix = "unknown secure setting"; + String msgPrefix = (secureSettings != null && secureSettings.getSettingNames().contains(key)) + ? "unknown secure setting" + : "unknown setting"; + if (key.startsWith(ARCHIVED_SETTINGS_PREFIX)) { + throw new IllegalArgumentException( + Strings.format( + "%s [%s] was archived after upgrading, and must be removed. See [%s] for details.", + msgPrefix, + key, + ReferenceDocs.ARCHIVED_SETTINGS + ) + ); } - String msg = msgPrefix + " [" + key + "]"; - List keys = scoredKeys.stream().map((a) -> a.v2()).toList(); + List keys = findSimilarKeys(key); if (keys.isEmpty() == false) { - msg += " did you mean " + (keys.size() == 1 ? "[" + keys.get(0) + "]" : "any of " + keys.toString()) + "?"; + throw new IllegalArgumentException( + Strings.format( + "%s [%s] did you mean %s?", + msgPrefix, + key, + (keys.size() == 1 ? "[" + keys.getFirst() + "]" : "any of " + keys) + ) + ); } else { - msg += " please check that any required plugins are installed, or check the breaking changes documentation for removed " - + "settings"; + throw new IllegalArgumentException( + Strings.format( + "%s [%s] please check that any required plugins are installed," + + " or check the breaking changes documentation for removed settings", + msgPrefix, + key + ) + ); } - throw new IllegalArgumentException(msg); } else { Set settingsDependencies = setting.getSettingsDependencies(key); if (setting.hasComplexMatcher()) { @@ -618,6 +631,19 @@ void validate(final String key, final Settings settings, final boolean validateV } } + private List findSimilarKeys(String key) { + LevenshteinDistance ld = new LevenshteinDistance(); + List> scoredKeys = new ArrayList<>(); + for (String k : this.keySettings.keySet()) { + float distance = ld.getDistance(key, k); + if (distance > 0.7f) { + scoredKeys.add(new Tuple<>(distance, k)); + } + } + CollectionUtil.timSort(scoredKeys, (a, b) -> b.v1().compareTo(a.v1())); + return scoredKeys.stream().map((a) -> a.v2()).toList(); + } + /** * Transactional interface to update settings. * @see Setting diff --git a/server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt b/server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt index 8f97a935a5e80..ac611e5700373 100644 --- a/server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt +++ b/server/src/main/resources/org/elasticsearch/common/reference-docs-links.txt @@ -46,4 +46,5 @@ ALLOCATION_EXPLAIN_NO_COPIES troubleshoot/ela ALLOCATION_EXPLAIN_MAX_RETRY troubleshoot/elasticsearch/diagnose-unassigned-shards#maximum-retries-exceeded SECURE_SETTINGS deploy-manage/security/secure-settings CLUSTER_SHARD_LIMIT reference/elasticsearch/configuration-reference/miscellaneous-cluster-settings#cluster-shard-limit -DELETE_INDEX_BLOCK api/doc/elasticsearch/operation/operation-indices-remove-block \ No newline at end of file +DELETE_INDEX_BLOCK api/doc/elasticsearch/operation/operation-indices-remove-block +ARCHIVED_SETTINGS deploy-manage/upgrade/deployment-or-cluster/archived-settings diff --git a/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index 253abcf93dace..8b61721e9e73e 100644 --- a/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -335,6 +335,23 @@ public Iterator> settings() { assertThat(e3.getMessage(), equalTo("too long")); } + public void testValidateArchivedSetting() { + IndexScopedSettings settings = new IndexScopedSettings(Settings.EMPTY, IndexScopedSettings.BUILT_IN_INDEX_SETTINGS); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> settings.validate(Settings.builder().put("archived.index.store.type", "boom").build(), false) + ); + assertThat( + e.getMessage(), + equalTo( + "unknown setting [archived.index.store.type] was archived after upgrading, and must be removed." + + " See [https://www.elastic.co/docs/deploy-manage/upgrade/deployment-or-cluster/archived-settings?version=master] " + + "for details." + ) + ); + + } + public void testTupleAffixUpdateConsumer() { String prefix = randomAlphaOfLength(3) + "foo."; String intSuffix = randomAlphaOfLength(3); From 9ba3b69f0717a2ec9fe9212459563551eaead2b1 Mon Sep 17 00:00:00 2001 From: Matteo Mazzola Date: Tue, 2 Dec 2025 11:17:42 +0000 Subject: [PATCH 2/2] Update ScopedSettingsTests.java --- .../org/elasticsearch/common/settings/ScopedSettingsTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java b/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java index 8b61721e9e73e..25ea8030e6277 100644 --- a/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java @@ -345,7 +345,7 @@ public void testValidateArchivedSetting() { e.getMessage(), equalTo( "unknown setting [archived.index.store.type] was archived after upgrading, and must be removed." - + " See [https://www.elastic.co/docs/deploy-manage/upgrade/deployment-or-cluster/archived-settings?version=master] " + + " See [https://www.elastic.co/docs/deploy-manage/upgrade/deployment-or-cluster/archived-settings?version=9.1] " + "for details." ) );