-
Notifications
You must be signed in to change notification settings - Fork 126
Description
What is the bug?
Problem:
When users create a snapshot policy, we don't check if inputs provided are valid. This becomes an issue especially with the Maximum age of snapshots retained field where users can enter any large value.
Here's what happens: The system accepts the policy creation without any checks. However, when you try to fetch this policy later, it fails because max age value (like 106751.9d) are too large or contain decimals that OpenSearch can't handle.

Current behavior:
- Policy gets created successfully without any validation
- When trying to fetch the policy later, it fails with parsing errors
- This happens because the entered value exceeds the maximum supported TimeValue in OpenSearch
public static TimeValue timeValueDays(long days) {
// 106751.9 days is Long.MAX_VALUE nanoseconds, so we cannot store 106752 days
if (days > 106751) {
throw new IllegalArgumentException("time value cannot store values greater than 106751 days");
}
return new TimeValue(days, TimeUnit.DAYS);
}
OpenSearchStatusException[Failed to retrieve policies before create/update policy because java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported]
OpenSearchStatusException[Failed to retrieve policies before create/update policy because java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported]
java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported
java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported
java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported
java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported
2025-07-10T09:00:17,692][ERROR][o.o.i.s.a.t.g.TransportGetSMPoliciesAction] [73b79944528cfff5d8c46cef8072a0a4] Failed to parse snapshot management policy in search response
java.lang.IllegalArgumentException: failed to parse [106751.9d], fractional time values are not supported
at org.opensearch.common.unit.TimeValue.parse(TimeValue.java:431)
at org.opensearch.common.unit.TimeValue.parseTimeValue(TimeValue.java:399)
at org.opensearch.common.unit.TimeValue.parseTimeValue(TimeValue.java:376)
at org.opensearch.indexmanagement.snapshotmanagement.model.SMPolicy$DeleteCondition$Companion.parse(SMPolicy.kt:403)
at org.opensearch.indexmanagement.snapshotmanagement.model.SMPolicy$Deletion$Companion.parse(SMPolicy.kt:333)
at org.opensearch.indexmanagement.snapshotmanagement.model.SMPolicy$Companion.parse(SMPolicy.kt:158)
at org.opensearch.indexmanagement.snapshotmanagement.api.transport.get.TransportGetSMPoliciesAction$parseGetAllPoliciesResponse$1$1.invoke(TransportGetSMPoliciesAction.kt:114)
at org.opensearch.indexmanagement.snapshotmanagement.api.transport.get.TransportGetSMPoliciesAction$parseGetAllPoliciesResponse$1$1.invoke(TransportGetSMPoliciesAction.kt:114)
at org.opensearch.indexmanagement.opensearchapi.OpenSearchExtensionsKt.parseWithType(OpenSearchExtensions.kt:275)
at org.opensearch.indexmanagement.snapshotmanagement.api.transport.get.TransportGetSMPoliciesAction.parseGetAllPoliciesResponse(TransportGetSMPoliciesAction.kt:114)
at org.opensearch.indexmanagement.snapshotmanagement.api.transport.get.TransportGetSMPoliciesAction.getAllPolicies(TransportGetSMPoliciesAction.kt:75)
at org.opensearch.indexmanagement.snapshotmanagement.api.transport.get.TransportGetSMPoliciesAction.access$getAllPolicies(TransportGetSMPoliciesAction.kt:40)
at org.opensearch.indexmanagement.snapshotmanagement.api.transport.get.TransportGetSMPoliciesAction$getAllPolicies$1.invokeSuspend(TransportGetSMPoliciesAction.kt)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Caused by: java.lang.NumberFormatException: For input string: "106751.9"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Long.parseLong(Long.java:709)
at java.base/java.lang.Long.parseLong(Long.java:832)
at org.opensearch.common.unit.TimeValue.parse(TimeValue.java:415)
... 18 more
curl -a "localhost:9200/_plugins/_sm/policies
{"error":{"root_cause":[{"type":"status_exception","reason":"Failed to parse snapshot management policy"}],"type":"status_exception","reason":"Failed to parse snapshot management policy"},"status":404}
Solution
We need to add validation when users create or update policies. This will prevent users from entering values that OpenSearch can't handle, and they'll get clear error messages right away instead of finding out later that their policy isn't working.
We need to explore where can we have these validation, in the dashboard side or plugin side.
ISM plugin:
Lines 65 to 75 in ca0416c
private suspend fun indexSMPolicy(request: IndexSMPolicyRequest, user: User?): IndexSMPolicyResponse { | |
val policy = request.policy.copy(schemaVersion = IndexUtils.indexManagementConfigSchemaVersion, user = user) | |
val indexReq = | |
request.index(INDEX_MANAGEMENT_INDEX) | |
.source(policy.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)) | |
.id(policy.id) | |
.routing(policy.id) // by default routed by id | |
val indexRes: IndexResponse = client.suspendUntil { index(indexReq, it) } | |
return IndexSMPolicyResponse(indexRes.id, indexRes.version, indexRes.seqNo, indexRes.primaryTerm, policy, indexRes.status()) | |
} |
Do you have any additional context?
Add any other context about the problem.