Debug ingest pipeline failures in Painless
When you convert time strings to nanoseconds in ingest pipelines, attempting to perform arithmetic operations directly on string values without proper date parsing causes type casting errors.
Follow these guidelines to avoid ingest pipeline errors in your Painless scripts:
- Time strings such as
"HH:mm:ss.SSS"must be explicitly parsed before performing arithmetic operations. - Using
SimpleDateFormatin a script processor allows custom parsing.
For details, refer to the following sample error, solution, and the result when the solution is applied.
{
"docs": [
{
"error": {
"root_cause": [
{
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx.nanoseconds = ctx.time_field * 1000000;",
" ^---- HERE"
],
"script": " ...",
"lang": "painless",
"position": {
"offset": 32,
"start": 11,
"end": 63
}
}
],
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx.nanoseconds = ctx.time_field * 1000000;",
" ^---- HERE"
],
"script": " ...",
"lang": "painless",
"position": {
"offset": 32,
"start": 11,
"end": 63
},
"caused_by": {
"type": "class_cast_exception",
"reason": "Cannot apply [*] operation to types [java.lang.String] and [java.lang.Integer]."
}
}
}
]
}
{
"script": {
"source": """
ctx.nanoseconds = ctx.time_field * 1000000;
"""
}
}
When accessing fields using ctx.time_field in ingest pipelines, the values are not automatically parsed to their mapped field types. The script attempts to multiply a string value (time field) directly with an integer. Time strings such as "00:00:00.022" remain as strings. They need to be properly parsed as dates and converted to epoch milliseconds before performing arithmetic operations.
Parse the time string directly using SimpleDateFormat and get epoch milliseconds:
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description": "Parse time and convert to nanoseconds",
"processors": [
{
"script": {
"source": """
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
long millis = sdf.parse(ctx.time_field).getTime();
ctx.timestamp_nanos = millis * 1000000L;
"""
}
}
]
},
"docs": [
{
"_index": "index",
"_id": "id",
"_source": {
"time_field": "00:00:00.022"
}
}
]
}
{
"docs": [
{
"doc": {
"_index": "index",
"_version": "-3",
"_id": "id",
"_source": {
"time_field": "00:00:00.022",
"timestamp_nanos": 22000000
},
"_ingest": {
"timestamp": "2025-09-02T17:40:42.175772728Z"
}
}
}
]
}