Skip to content

XContent Serialisation of SnapshotInvocationRecord can include extremely long string that cannot be read back by x-content parser #96918

@original-brownbear

Description

@original-brownbear

We've seen a case where a serialised version of SnapshotInvocationRecord contains a details string that exceeded Jackson's limit:

Caused by: org.elasticsearch.xcontent.XContentParseException: [-1:6050591] [snapshot_policy_invocation_record] failed to parse field [details]	at org.elasticsearch.xcontent.ObjectParser.throwFailedToParse(ObjectParser.java:616) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseValue(ObjectParser.java:611) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseSub(ObjectParser.java:657) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parse(ObjectParser.java:315) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.parse(ConstructingObjectParser.java:166) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.apply(ConstructingObjectParser.java:158) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord.parse(SnapshotInvocationRecord.java:54) ~[?:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareField$10(ObjectParser.java:431) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseValue(ObjectParser.java:609) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseSub(ObjectParser.java:629) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parse(ObjectParser.java:315) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.parse(ConstructingObjectParser.java:166) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.apply(ConstructingObjectParser.java:158) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata.parse(SnapshotLifecyclePolicyMetadata.java:88) ~[?:?]	at org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata.lambda$static$2(SnapshotLifecycleMetadata.java:71) ~[?:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareNamedObjects$14(ObjectParser.java:492) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareNamedObjects$15(ObjectParser.java:505) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseValue(ObjectParser.java:609) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseSub(ObjectParser.java:629) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parse(ObjectParser.java:315) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.parse(ConstructingObjectParser.java:166) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xpack.ilm.IndexLifecycle.lambda$xContentEntries$3(IndexLifecycle.java:304) ~[?:?]	at org.elasticsearch.xcontent.NamedXContentRegistry$Entry.lambda$new$0(NamedXContentRegistry.java:54) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.NamedXContentRegistry.parseNamedObject(NamedXContentRegistry.java:147) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.support.AbstractXContentParser.namedObject(AbstractXContentParser.java:414) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.cluster.metadata.Metadata$Builder.fromXContent(Metadata.java:2663) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.readXContent(PersistedClusterStateService.java:671) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.lambda$loadOnDiskState$6(PersistedClusterStateService.java:571) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.consumeFromType(PersistedClusterStateService.java:706) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.loadOnDiskState(PersistedClusterStateService.java:570) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.loadBestOnDiskState(PersistedClusterStateService.java:494) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.loadBestOnDiskState(PersistedClusterStateService.java:409) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.GatewayMetaState.createOnDiskPersistedState(GatewayMetaState.java:167) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.GatewayMetaState.createPersistedState(GatewayMetaState.java:144) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.GatewayMetaState.start(GatewayMetaState.java:104) ~[elasticsearch-8.8.1.jar:?]	... 4 more Caused by: com.fasterxml.jackson.core.exc.StreamConstraintsException: String length (5043368) exceeds the maximum length (5000000)	at com.fasterxml.jackson.core.StreamReadConstraints.validateStringLength(StreamReadConstraints.java:290) ~[?:?]	at com.fasterxml.jackson.core.util.ReadConstrainedTextBuffer.validateStringLength(ReadConstrainedTextBuffer.java:27) ~[?:?]	at com.fasterxml.jackson.core.util.TextBuffer.finishCurrentSegment(TextBuffer.java:931) ~[?:?]	at com.fasterxml.jackson.dataformat.smile.SmileParser._decodeLongUnicodeValue(SmileParser.java:2538) ~[?:?]	at com.fasterxml.jackson.dataformat.smile.SmileParser._finishToken(SmileParser.java:2037) ~[?:?]	at com.fasterxml.jackson.dataformat.smile.SmileParser.getText(SmileParser.java:1078) ~[?:?]	at org.elasticsearch.xcontent.provider.json.JsonXContentParser.text(JsonXContentParser.java:109) ~[?:?]	at org.elasticsearch.xcontent.AbstractObjectParser.lambda$declareField$0(AbstractObjectParser.java:174) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareField$10(ObjectParser.java:431) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseValue(ObjectParser.java:609) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseSub(ObjectParser.java:657) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parse(ObjectParser.java:315) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.parse(ConstructingObjectParser.java:166) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.apply(ConstructingObjectParser.java:158) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord.parse(SnapshotInvocationRecord.java:54) ~[?:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareField$10(ObjectParser.java:431) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseValue(ObjectParser.java:609) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseSub(ObjectParser.java:629) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parse(ObjectParser.java:315) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.parse(ConstructingObjectParser.java:166) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.apply(ConstructingObjectParser.java:158) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata.parse(SnapshotLifecyclePolicyMetadata.java:88) ~[?:?]	at org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata.lambda$static$2(SnapshotLifecycleMetadata.java:71) ~[?:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareNamedObjects$14(ObjectParser.java:492) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.lambda$declareNamedObjects$15(ObjectParser.java:505) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseValue(ObjectParser.java:609) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parseSub(ObjectParser.java:629) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ObjectParser.parse(ObjectParser.java:315) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.ConstructingObjectParser.parse(ConstructingObjectParser.java:166) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xpack.ilm.IndexLifecycle.lambda$xContentEntries$3(IndexLifecycle.java:304) ~[?:?]	at org.elasticsearch.xcontent.NamedXContentRegistry$Entry.lambda$new$0(NamedXContentRegistry.java:54) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.NamedXContentRegistry.parseNamedObject(NamedXContentRegistry.java:147) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.xcontent.support.AbstractXContentParser.namedObject(AbstractXContentParser.java:414) ~[elasticsearch-x-content-8.8.1.jar:?]	at org.elasticsearch.cluster.metadata.Metadata$Builder.fromXContent(Metadata.java:2663) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.readXContent(PersistedClusterStateService.java:671) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.lambda$loadOnDiskState$6(PersistedClusterStateService.java:571) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.consumeFromType(PersistedClusterStateService.java:706) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.loadOnDiskState(PersistedClusterStateService.java:570) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.loadBestOnDiskState(PersistedClusterStateService.java:494) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.PersistedClusterStateService.loadBestOnDiskState(PersistedClusterStateService.java:409) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.GatewayMetaState.createOnDiskPersistedState(GatewayMetaState.java:167) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.GatewayMetaState.createPersistedState(GatewayMetaState.java:144) ~[elasticsearch-8.8.1.jar:?]	at org.elasticsearch.gateway.GatewayMetaState.start(GatewayMetaState.java:104) ~[elasticsearch-8.8.1.jar:?]	... 4 more 

A 5M chars string isn't acceptable in the cluster state to begin with and we must change what we serialise here to avoid such long strings.
I will separately look into hardening the CS deserialisation logic here.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions