Table of Contents
1. Introduction
I found bug that was already reported and get to know that will be repaired with release of Elasticsearch 8.12.0 version. Recently new package become available so I decided to quickly check how this bug was fixed. Basically whenever you were calling Debug.explain method inside painless script it was causing an error and killing Elasticsearch node. Let’s figure out how it is right now.
2. Start Elasticsearch
docker run \
--name elk01 \
-e node.name="elk01" \
-p 9200:9200 \
docker.elastic.co/elasticsearch/elasticsearch:8.11.3
set password for ‘elastic’ user
# reset password
docker exec -it elk01 bash -c "(mkfifo pipe1); ( (elasticsearch-reset-password -u elastic -i < pipe1) & ( echo $'y\n123456\n123456' > pipe1) );sleep 5;rm pipe1"
3. Load test data
This test data I you will refer to in painless script
# load test data
curl -k -u elastic:123456 -XPOST "https://localhost:9200/fruits/_bulk" \
-H 'content-type: application/json' -d'
{"index":{"_id":"1"}}
{"name_base64":"QXBwbGU=","color_hex":"477265656e"}
{"index":{"_id":"2"}}
{"name_base64":"QW5hbmFz","color_hex":"59656c6c6f77"}
{"index":{"_id":"3"}}
{"name_base64":"Q2hlcnJ5","color_hex":"526564"}
'
4. Use Debug.explain and kill node
curl -k -u elastic:123456 -XGET "https://localhost:9200/fruits/_search?pretty" \
-H 'content-type: application/json' -d'
{
"query": {
"bool": {
"filter": {
"script": {
"script": {
"source": "Debug.explain($(params.field,\"\"))",
"params": {
"field": "name_base64.keyword",
"filteronvalue": "Apple"
}
}
}
}
}
}
}'
this will kill node with error like
{ "@timestamp": "2024-01-02T01:18:01.368Z", "log.level": "ERROR", "message": "fatal error in thread [elasticsearch[elk01][search_worker][T#1]], exiting", "ecs.version": "1.2.0", "service.name": "ES_ECS", "event.dataset": "elasticsearch.server", "process.thread.name": "elasticsearch[elk01][search_worker][T#1]", "log.logger": "org.elasticsearch.bootstrap.ElasticsearchUncaughtExceptionHandler", "elasticsearch.cluster.uuid": "ugbWxHNTTDSp2S2CjIGgOw", "elasticsearch.node.id": "7FwCyEVxS2C6OMAfP_CcMw", "elasticsearch.node.name": "elk01", "elasticsearch.cluster.name": "docker-cluster", "error.type": "org.elasticsearch.painless.PainlessExplainError", "error.stack_trace": "org.elasticsearch.painless.PainlessExplainError\n\tat org.elasticsearch.painless@8.11.3/org.elasticsearch.painless.api.Debug.explain(Debug.java:23)\n\tat org.elasticsearch.painless.PainlessScript$Script.execute(Debug.explain($(params.field,\"\")):15)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.index.query.ScriptQueryBuilder$ScriptQuery$1$1.matches(ScriptQueryBuilder.java:194)\n\tat org.apache.lucene.core@9.8.0/org.apache.lucene.search.ConstantScoreScorer$1.matches(ConstantScoreScorer.java:107)\n\tat org.apache.lucene.core@9.8.0/org.apache.lucene.search.Weight$DefaultBulkScorer.scoreRange(Weight.java:295)\n\tat org.apache.lucene.core@9.8.0/org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:236)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.search.internal.CancellableBulkScorer.score(CancellableBulkScorer.java:45)\n\tat org.apache.lucene.core@9.8.0/org.apache.lucene.search.BulkScorer.score(BulkScorer.java:38)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.search.internal.ContextIndexSearcher.searchLeaf(ContextIndexSearcher.java:536)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.search.internal.ContextIndexSearcher.search(ContextIndexSearcher.java:460)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.search.internal.ContextIndexSearcher.lambda$search$4(ContextIndexSearcher.java:375)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:33)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:983)\n\tat org.elasticsearch.server@8.11.3/org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)\n\tat java.base/java.lang.Thread.run(Thread.java:1583)\n" }
5. Check version 8.12.0
Run newest version
console.log( 'Code is Poetry' );
and repeat steps from 2 to 4
docker remove elk01
docker run \
--name elk01 \
-e node.name="elk01" \
-p 9200:9200 \
docker.elastic.co/elasticsearch/elasticsearch:8.12.0
now after executing query from step 4 you should see response similar
{
"error" : {
"root_cause" : [
{
"type" : "painless_explain_error",
"reason" : null
}
],
"type" : "search_phase_execution_exception",
"reason" : "all shards failed",
"phase" : "query",
"grouped" : true,
"failed_shards" : [
{
"shard" : 0,
"index" : "fruits",
"node" : "_Duyp1zgQZOngOgRN9QtQw",
"reason" : {
"type" : "script_exception",
"reason" : "runtime error",
"painless_class" : "java.lang.String",
"to_string" : "QXBwbGU=",
"java_class" : "java.lang.String",
"script_stack" : [
"Debug.explain($(params.field,\"\"))",
" ^---- HERE"
],
"script" : "Debug.explain($(params.field,\"\"))",
"lang" : "painless",
"position" : {
"offset" : 14,
"start" : 0,
"end" : 33
},
"caused_by" : {
"type" : "painless_explain_error",
"reason" : null
}
}
}
],
"caused_by" : {
"type" : "painless_explain_error",
"reason" : null
}
},
"status" : 400
}
6. Conclusion
So finally bug got fixed and now from version 8.12.0 you can work again with Debug.explain method.