From 5cb32100a80dd6fafe500f43a823362a8db388f7 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Thu, 17 Jul 2025 16:10:31 -0400 Subject: [PATCH 01/10] Naively increase the meta field char limit 50->500 --- .../elasticsearch/mapping-reference/mapping-field-meta.md | 2 +- .../main/java/org/elasticsearch/index/mapper/TypeParsers.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md b/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md index 33a467e6fbc43..1ea0d00d8149e 100644 --- a/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md +++ b/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md @@ -24,7 +24,7 @@ PUT my-index-000001 ``` ::::{note} -Field metadata enforces at most 5 entries, that keys have a length that is less than or equal to 20, and that values are strings whose length is less than or equal to 50. +Field metadata enforces at most 5 entries, that keys have a length that is less than or equal to 20, and that values are strings whose length is less than or equal to 500. :::: diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java index 7be9d658297ca..43da6c1172312 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java @@ -54,9 +54,9 @@ public static Map parseMeta(String name, Object metaObject) { } for (Object value : meta.values()) { if (value instanceof String sValue) { - if (sValue.codePointCount(0, sValue.length()) > 50) { + if (sValue.codePointCount(0, sValue.length()) > 500) { throw new MapperParsingException( - "[meta] values can't be longer than 50 chars, but got [" + value + "] for field [" + name + "]" + "[meta] values can't be longer than 500 chars, but got [" + value + "] for field [" + name + "]" ); } } else if (value == null) { From c4f2b927bfadf1404f6fd5ff0a445fc582a98a1c Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Jul 2025 11:33:29 -0400 Subject: [PATCH 02/10] Adjust test to account for 500 char limit --- .../java/org/elasticsearch/index/mapper/TypeParsersTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java index 9a30e7d696b68..b1ec17cd3cc6e 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java @@ -161,10 +161,10 @@ public void testParseMeta() { } { - String longString = IntStream.range(0, 51).mapToObj(Integer::toString).collect(Collectors.joining()); + String longString = IntStream.range(0, 501).mapToObj(Integer::toString).collect(Collectors.joining()); Map mapping = Map.of("foo", longString); MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", mapping)); - assertThat(e.getMessage(), Matchers.startsWith("[meta] values can't be longer than 50 chars")); + assertThat(e.getMessage(), Matchers.startsWith("[meta] values can't be longer than 500 chars")); } } } From 444a8beea42b11e730520256127654ec4765958d Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Jul 2025 14:55:14 -0400 Subject: [PATCH 03/10] Added index setting for field meta character limit --- .../common/settings/IndexScopedSettings.java | 1 + .../elasticsearch/index/IndexSettings.java | 8 ++ .../index/mapper/FieldMapper.java | 2 +- .../index/mapper/TypeParsers.java | 17 ++- .../index/mapper/TypeParsersTests.java | 108 ++++++++++++------ 5 files changed, 97 insertions(+), 39 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index 93ddb5d3fc485..1873fc355a0a5 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -204,6 +204,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings { IndexSettings.INDEX_MAPPER_SOURCE_MODE_SETTING, IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING, InferenceMetadataFieldsMapper.USE_LEGACY_SEMANTIC_TEXT_FORMAT, + IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, // validate that built-in similarities don't get redefined Setting.groupSetting("index.similarity.", (s) -> { diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java index a6335ca6666b0..156313b17a5a4 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -856,6 +856,14 @@ private static String getIgnoreAboveDefaultValue(final Settings settings) { Property.ServerlessPublic ); + public static final Setting INDEX_MAPPING_META_LENGTH_LIMIT_SETTING = Setting.intSetting( + "index.mapping.meta.length_limit", + 500, // default value + 20, // minimum value + Property.IndexScope, + Property.Final + ); + private final Index index; private final IndexVersion version; private final Logger logger; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index a43575b8f990c..847f4740e21fb 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -1298,7 +1298,7 @@ public static Parameter> metaParam() { "meta", true, Map::of, - (n, c, o) -> TypeParsers.parseMeta(n, o), + (n, c, o) -> TypeParsers.parseMeta(n, o, c), m -> m.fieldType().meta(), XContentBuilder::stringStringMap, Objects::toString diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java index 43da6c1172312..355821cb07122 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java @@ -24,14 +24,12 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.isArray; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue; +import static org.elasticsearch.index.IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; public class TypeParsers { private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(TypeParsers.class); - /** - * Parse the {@code meta} key of the mapping. - */ - public static Map parseMeta(String name, Object metaObject) { + public static Map parseMeta(String name, Object metaObject, MappingParserContext parserContext) { if (metaObject instanceof Map == false) { throw new MapperParsingException( "[meta] must be an object, got " + metaObject.getClass().getSimpleName() + "[" + metaObject + "] for field [" + name + "]" @@ -52,11 +50,18 @@ public static Map parseMeta(String name, Object metaObject) { ); } } + int metaValueLengthLimit = INDEX_MAPPING_META_LENGTH_LIMIT_SETTING.get(parserContext.getIndexSettings().getSettings()); for (Object value : meta.values()) { if (value instanceof String sValue) { - if (sValue.codePointCount(0, sValue.length()) > 500) { + if (sValue.codePointCount(0, sValue.length()) > metaValueLengthLimit) { throw new MapperParsingException( - "[meta] values can't be longer than 500 chars, but got [" + value + "] for field [" + name + "]" + "[meta] values can't be longer than " + + metaValueLengthLimit + + " chars, but got [" + + value + + "] for field [" + + name + + "]" ); } } else if (value == null) { diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java index b1ec17cd3cc6e..fc45de1eca5fb 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java @@ -52,48 +52,32 @@ private static Map defaultAnalyzers() { return analyzers; } - public void testMultiFieldWithinMultiField() throws IOException { - - XContentBuilder mapping = XContentFactory.jsonBuilder() - .startObject() - .field("type", "keyword") - .startObject("fields") - .startObject("sub-field") - .field("type", "keyword") - .startObject("fields") - .startObject("sub-sub-field") - .field("type", "keyword") - .endObject() - .endObject() - .endObject() - .endObject() - .endObject(); + private Settings buildSettings() { + return Settings.builder() + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1) + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) + .build(); + } + private MappingParserContext createParserContext(Settings settings) { Mapper.TypeParser typeParser = KeywordFieldMapper.PARSER; MapperService mapperService = mock(MapperService.class); IndexAnalyzers indexAnalyzers = IndexAnalyzers.of(defaultAnalyzers()); when(mapperService.getIndexAnalyzers()).thenReturn(indexAnalyzers); - Settings settings = Settings.builder() - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()) - .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1) - .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) - .build(); IndexMetadata metadata = IndexMetadata.builder("test").settings(settings).build(); IndexSettings indexSettings = new IndexSettings(metadata, Settings.EMPTY); when(mapperService.getIndexSettings()).thenReturn(indexSettings); - // For indices created in 8.0 or later, we should throw an error. - Map fieldNodeCopy = XContentHelper.convertToMap(BytesReference.bytes(mapping), true, mapping.contentType()).v2(); - IndexVersion version = IndexVersionUtils.randomVersionBetween(random(), IndexVersions.V_8_0_0, IndexVersion.current()); TransportVersion transportVersion = TransportVersionUtils.randomVersionBetween( random(), TransportVersions.V_8_0_0, TransportVersion.current() ); - MappingParserContext context = new MappingParserContext( + return new MappingParserContext( null, type -> typeParser, type -> null, @@ -108,6 +92,29 @@ public void testMultiFieldWithinMultiField() throws IOException { throw new UnsupportedOperationException(); } ); + } + + public void testMultiFieldWithinMultiField() throws IOException { + + XContentBuilder mapping = XContentFactory.jsonBuilder() + .startObject() + .field("type", "keyword") + .startObject("fields") + .startObject("sub-field") + .field("type", "keyword") + .startObject("fields") + .startObject("sub-sub-field") + .field("type", "keyword") + .endObject() + .endObject() + .endObject() + .endObject() + .endObject(); + + // For indices created in 8.0 or later, we should throw an error. + Map fieldNodeCopy = XContentHelper.convertToMap(BytesReference.bytes(mapping), true, mapping.contentType()).v2(); + + MappingParserContext context = createParserContext(buildSettings()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> { TextFieldMapper.PARSER.parse("textField", fieldNodeCopy, context); @@ -122,49 +129,86 @@ public void testMultiFieldWithinMultiField() throws IOException { } public void testParseMeta() { + MappingParserContext parserContext = createParserContext(buildSettings()); + { - MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", 3)); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", 3, parserContext) + ); assertEquals("[meta] must be an object, got Integer[3] for field [foo]", e.getMessage()); } { MapperParsingException e = expectThrows( MapperParsingException.class, - () -> TypeParsers.parseMeta("foo", Map.of("veryloooooooooooongkey", 3L)) + () -> TypeParsers.parseMeta("foo", Map.of("veryloooooooooooongkey", 3L), parserContext) ); assertEquals("[meta] keys can't be longer than 20 chars, but got [veryloooooooooooongkey] for field [foo]", e.getMessage()); } { Map mapping = Map.of("foo1", 3L, "foo2", 4L, "foo3", 5L, "foo4", 6L, "foo5", 7L, "foo6", 8L); - MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", mapping)); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", mapping, parserContext) + ); assertEquals("[meta] can't have more than 5 entries, but got 6 on field [foo]", e.getMessage()); } { Map mapping = Map.of("foo", Map.of("bar", "baz")); - MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", mapping)); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", mapping, parserContext) + ); assertEquals("[meta] values can only be strings, but got Map1[{bar=baz}] for field [foo]", e.getMessage()); } { Map mapping = Map.of("bar", "baz", "foo", 3); - MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", mapping)); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", mapping, parserContext) + ); assertEquals("[meta] values can only be strings, but got Integer[3] for field [foo]", e.getMessage()); } { Map meta = new HashMap<>(); meta.put("foo", null); - MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", meta)); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", meta, parserContext) + ); assertEquals("[meta] values can't be null (field [foo])", e.getMessage()); } { String longString = IntStream.range(0, 501).mapToObj(Integer::toString).collect(Collectors.joining()); Map mapping = Map.of("foo", longString); - MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", mapping)); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", mapping, parserContext) + ); assertThat(e.getMessage(), Matchers.startsWith("[meta] values can't be longer than 500 chars")); } + + { + Settings otherSettings = Settings.builder() + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1) + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING.getKey(), 300) + .build(); + MappingParserContext otherParserContext = createParserContext(otherSettings); + String longString = IntStream.range(0, 301).mapToObj(Integer::toString).collect(Collectors.joining()); + Map mapping = Map.of("foo", longString); + MapperParsingException e = expectThrows( + MapperParsingException.class, + () -> TypeParsers.parseMeta("foo", mapping, otherParserContext) + ); + assertThat(e.getMessage(), Matchers.startsWith("[meta] values can't be longer than 300 chars")); + } } } From a685e7e6d6676423ae2c0eb3e80281bacf0b53f3 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Jul 2025 15:04:07 -0400 Subject: [PATCH 04/10] Min val should be 0, restored deleted comment --- .../elasticsearch/mapping-reference/mapping-field-meta.md | 1 + .../src/main/java/org/elasticsearch/index/IndexSettings.java | 4 ++-- .../main/java/org/elasticsearch/index/mapper/TypeParsers.java | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md b/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md index 1ea0d00d8149e..cdcafd43a0877 100644 --- a/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md +++ b/docs/reference/elasticsearch/mapping-reference/mapping-field-meta.md @@ -25,6 +25,7 @@ PUT my-index-000001 ::::{note} Field metadata enforces at most 5 entries, that keys have a length that is less than or equal to 20, and that values are strings whose length is less than or equal to 500. +The value limit is configurable, with the index setting: `index.mapping.meta.length_limit`. :::: diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java index 156313b17a5a4..098897ffdf077 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -858,8 +858,8 @@ private static String getIgnoreAboveDefaultValue(final Settings settings) { public static final Setting INDEX_MAPPING_META_LENGTH_LIMIT_SETTING = Setting.intSetting( "index.mapping.meta.length_limit", - 500, // default value - 20, // minimum value + 500, + 0, Property.IndexScope, Property.Final ); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java index 355821cb07122..71d4b2eb8bbe9 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java @@ -29,6 +29,9 @@ public class TypeParsers { private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(TypeParsers.class); + /** + * Parse the {@code meta} key of the mapping. + */ public static Map parseMeta(String name, Object metaObject, MappingParserContext parserContext) { if (metaObject instanceof Map == false) { throw new MapperParsingException( From 4e5190187cb5997f6800c36b6fec337a1484dba6 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Jul 2025 16:35:06 -0400 Subject: [PATCH 05/10] Move setting to MappterService --- .../common/settings/IndexScopedSettings.java | 3 ++- .../main/java/org/elasticsearch/index/IndexSettings.java | 8 -------- .../org/elasticsearch/index/mapper/MapperService.java | 7 +++++++ .../java/org/elasticsearch/index/mapper/TypeParsers.java | 2 +- .../org/elasticsearch/index/mapper/TypeParsersTests.java | 3 ++- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index 1873fc355a0a5..a58cc64ad0f1f 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -173,6 +173,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings { MapperService.INDEX_MAPPING_DIMENSION_FIELDS_LIMIT_SETTING, MapperService.INDEX_MAPPING_FIELD_NAME_LENGTH_LIMIT_SETTING, MapperService.INDEX_MAPPER_DYNAMIC_SETTING, + MapperService.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, BitsetFilterCache.INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING, IndexModule.INDEX_STORE_TYPE_SETTING, IndexModule.INDEX_STORE_PRE_LOAD_SETTING, @@ -204,7 +205,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings { IndexSettings.INDEX_MAPPER_SOURCE_MODE_SETTING, IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING, InferenceMetadataFieldsMapper.USE_LEGACY_SEMANTIC_TEXT_FORMAT, - IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, + // IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, // validate that built-in similarities don't get redefined Setting.groupSetting("index.similarity.", (s) -> { diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java index 098897ffdf077..a6335ca6666b0 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -856,14 +856,6 @@ private static String getIgnoreAboveDefaultValue(final Settings settings) { Property.ServerlessPublic ); - public static final Setting INDEX_MAPPING_META_LENGTH_LIMIT_SETTING = Setting.intSetting( - "index.mapping.meta.length_limit", - 500, - 0, - Property.IndexScope, - Property.Final - ); - private final Index index; private final IndexVersion version; private final Logger logger; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 7958fd8e51525..8ca367d29fe24 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -175,6 +175,13 @@ public boolean isAutoUpdate() { Property.IndexScope, Property.IndexSettingDeprecatedInV7AndRemovedInV8 ); + public static final Setting INDEX_MAPPING_META_LENGTH_LIMIT_SETTING = Setting.intSetting( + "index.mapping.meta.length_limit", + 500, + 0, + Property.IndexScope, + Property.Final + ); private final IndexAnalyzers indexAnalyzers; private final MappingParser mappingParser; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java index 71d4b2eb8bbe9..67bff1f9bd7e4 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java @@ -24,7 +24,7 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.isArray; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue; -import static org.elasticsearch.index.IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; +import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; public class TypeParsers { private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(TypeParsers.class); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java index fc45de1eca5fb..48312ccd49f8c 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java @@ -38,6 +38,7 @@ import static org.elasticsearch.index.analysis.AnalysisRegistry.DEFAULT_ANALYZER_NAME; import static org.elasticsearch.index.analysis.AnalysisRegistry.DEFAULT_SEARCH_ANALYZER_NAME; import static org.elasticsearch.index.analysis.AnalysisRegistry.DEFAULT_SEARCH_QUOTED_ANALYZER_NAME; +import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; import static org.hamcrest.core.IsEqual.equalTo; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -199,7 +200,7 @@ public void testParseMeta() { .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()) .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1) .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) - .put(IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING.getKey(), 300) + .put(INDEX_MAPPING_META_LENGTH_LIMIT_SETTING.getKey(), 300) .build(); MappingParserContext otherParserContext = createParserContext(otherSettings); String longString = IntStream.range(0, 301).mapToObj(Integer::toString).collect(Collectors.joining()); From 40356f6f128f268b7978601f4071b9689dc2cbce Mon Sep 17 00:00:00 2001 From: Sean Story Date: Fri, 18 Jul 2025 16:35:58 -0400 Subject: [PATCH 06/10] make it dynamic --- .../java/org/elasticsearch/index/mapper/MapperService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 8ca367d29fe24..603e61d9ff4ba 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -179,8 +179,8 @@ public boolean isAutoUpdate() { "index.mapping.meta.length_limit", 500, 0, - Property.IndexScope, - Property.Final + Property.Dynamic, + Property.IndexScope ); private final IndexAnalyzers indexAnalyzers; From 65a768d3404cb227c2bf119fae5a93c2a9b036c3 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Mon, 21 Jul 2025 12:05:44 -0400 Subject: [PATCH 07/10] remove commented-out line --- .../org/elasticsearch/common/settings/IndexScopedSettings.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index a58cc64ad0f1f..d908c99ca5bc2 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -205,7 +205,6 @@ public final class IndexScopedSettings extends AbstractScopedSettings { IndexSettings.INDEX_MAPPER_SOURCE_MODE_SETTING, IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING, InferenceMetadataFieldsMapper.USE_LEGACY_SEMANTIC_TEXT_FORMAT, - // IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, // validate that built-in similarities don't get redefined Setting.groupSetting("index.similarity.", (s) -> { From 5e8fcabeab2068dd5b565d6a9ee5df3e9c95c659 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Mon, 21 Jul 2025 12:58:56 -0400 Subject: [PATCH 08/10] Move setting back to IndexSettings --- .../common/settings/IndexScopedSettings.java | 2 +- .../main/java/org/elasticsearch/index/IndexSettings.java | 8 ++++++++ .../org/elasticsearch/index/mapper/MapperService.java | 7 ------- .../java/org/elasticsearch/index/mapper/TypeParsers.java | 2 +- .../org/elasticsearch/index/mapper/TypeParsersTests.java | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java index d908c99ca5bc2..1873fc355a0a5 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java @@ -173,7 +173,6 @@ public final class IndexScopedSettings extends AbstractScopedSettings { MapperService.INDEX_MAPPING_DIMENSION_FIELDS_LIMIT_SETTING, MapperService.INDEX_MAPPING_FIELD_NAME_LENGTH_LIMIT_SETTING, MapperService.INDEX_MAPPER_DYNAMIC_SETTING, - MapperService.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, BitsetFilterCache.INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING, IndexModule.INDEX_STORE_TYPE_SETTING, IndexModule.INDEX_STORE_PRE_LOAD_SETTING, @@ -205,6 +204,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings { IndexSettings.INDEX_MAPPER_SOURCE_MODE_SETTING, IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING, InferenceMetadataFieldsMapper.USE_LEGACY_SEMANTIC_TEXT_FORMAT, + IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, // validate that built-in similarities don't get redefined Setting.groupSetting("index.similarity.", (s) -> { diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java index a6335ca6666b0..8fc1d8432c72e 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -856,6 +856,14 @@ private static String getIgnoreAboveDefaultValue(final Settings settings) { Property.ServerlessPublic ); + public static final Setting INDEX_MAPPING_META_LENGTH_LIMIT_SETTING = Setting.intSetting( + "index.mapping.meta.length_limit", + 500, + 0, + Property.Dynamic, + Property.IndexScope + ); + private final Index index; private final IndexVersion version; private final Logger logger; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 603e61d9ff4ba..7958fd8e51525 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -175,13 +175,6 @@ public boolean isAutoUpdate() { Property.IndexScope, Property.IndexSettingDeprecatedInV7AndRemovedInV8 ); - public static final Setting INDEX_MAPPING_META_LENGTH_LIMIT_SETTING = Setting.intSetting( - "index.mapping.meta.length_limit", - 500, - 0, - Property.Dynamic, - Property.IndexScope - ); private final IndexAnalyzers indexAnalyzers; private final MappingParser mappingParser; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java index 67bff1f9bd7e4..71d4b2eb8bbe9 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeParsers.java @@ -24,7 +24,7 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.isArray; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue; -import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; +import static org.elasticsearch.index.IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; public class TypeParsers { private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(TypeParsers.class); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java index 48312ccd49f8c..95e2cf615179c 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java @@ -35,10 +35,10 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.elasticsearch.index.IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; import static org.elasticsearch.index.analysis.AnalysisRegistry.DEFAULT_ANALYZER_NAME; import static org.elasticsearch.index.analysis.AnalysisRegistry.DEFAULT_SEARCH_ANALYZER_NAME; import static org.elasticsearch.index.analysis.AnalysisRegistry.DEFAULT_SEARCH_QUOTED_ANALYZER_NAME; -import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING; import static org.hamcrest.core.IsEqual.equalTo; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; From 0dc5f31441d45c7a9b7576cf0939149dc21d1eed Mon Sep 17 00:00:00 2001 From: Sean Story Date: Mon, 21 Jul 2025 13:00:14 -0400 Subject: [PATCH 09/10] Add new setting to NON_REPLICATED_SETTINGS list --- .../xpack/ccr/action/TransportResumeFollowAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java index b0be3e21bbc7c..731d600836b77 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowAction.java @@ -496,6 +496,7 @@ static String[] extractLeaderShardHistoryUUIDs(Map ccrIndexMetad IndexSettings.INDEX_FLUSH_AFTER_MERGE_THRESHOLD_SIZE_SETTING, IndexSettings.INDEX_GC_DELETES_SETTING, IndexSettings.MAX_REFRESH_LISTENERS_PER_SHARD, + IndexSettings.INDEX_MAPPING_META_LENGTH_LIMIT_SETTING, IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING, BitsetFilterCache.INDEX_LOAD_RANDOM_ACCESS_FILTERS_EAGERLY_SETTING, SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING, From 73b7ba2084056cd8b72402f630d1287a74bfa1ec Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Mon, 21 Jul 2025 17:09:57 +0000 Subject: [PATCH 10/10] [CI] Auto commit changes from spotless --- .../elasticsearch/index/mapper/TypeParsersTests.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java index 95e2cf615179c..d18d43d327f5e 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeParsersTests.java @@ -133,10 +133,7 @@ public void testParseMeta() { MappingParserContext parserContext = createParserContext(buildSettings()); { - MapperParsingException e = expectThrows( - MapperParsingException.class, - () -> TypeParsers.parseMeta("foo", 3, parserContext) - ); + MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", 3, parserContext)); assertEquals("[meta] must be an object, got Integer[3] for field [foo]", e.getMessage()); } @@ -178,10 +175,7 @@ public void testParseMeta() { { Map meta = new HashMap<>(); meta.put("foo", null); - MapperParsingException e = expectThrows( - MapperParsingException.class, - () -> TypeParsers.parseMeta("foo", meta, parserContext) - ); + MapperParsingException e = expectThrows(MapperParsingException.class, () -> TypeParsers.parseMeta("foo", meta, parserContext)); assertEquals("[meta] values can't be null (field [foo])", e.getMessage()); }