-
Notifications
You must be signed in to change notification settings - Fork 25.5k
Description
Elasticsearch Version
9.2.0-SNAPSHOT
Installed Plugins
No response
Java Version
bundled
OS Version
Darwin
Problem Description
When an ES|QL async query is submitted (POST _query/async
), the headers in the response contain both a x-elasticsearch-async-id
and x-elasticsearch-async-is-running
:
{
"x-elasticsearch-async-is-running": "?1",
"x-elastic-product": "Elasticsearch",
"transfer-encoding": "chunked",
"x-opaque-id": "eb265ac8-a1ef-4d93-9e78-e5a50845d6df;kibana:application:discover:new;application:discover:new",
"content-type": "application/vnd.elasticsearch+json;compatible-with=9",
"took-nanos": "201111334",
"x-elasticsearch-async-id": "FnRUYVdrbElOUUR1VUdCUm1xZ3hHVncdd2RJMUtWU01SQlNmQk1icFgtNGp4QTo1NzU5MTY="
}
If the query takes a bit of time, then we poll on the ID returned in the first request. While the query is still running, the response headers from polling (GET _query/async/{id}
) do not contain the x-elasticsearch-async-id
and x-elasticsearch-async-is-running
headers:
{
"x-elastic-product": "Elasticsearch",
"transfer-encoding": "chunked",
"x-opaque-id": "5f8c8392-b269-496d-8c3e-76508e388cab;kibana:application:discover:new;application:discover:new",
"content-type": "application/json",
"took-nanos": "204451667"
}
However, when the request completes, the response from polling (still GET _query/async/{id}
) do contain these headers:
{
"x-elasticsearch-async-is-running": "?0",
"x-elastic-product": "Elasticsearch",
"transfer-encoding": "chunked",
"warning": "299 Elasticsearch-9.2.0-09250da4bdc785e783e9dbb221b489d665fa91b4 \"No limit defined, adding default limit of [1000]\"",
"x-opaque-id": "0aefa8fb-0e42-4488-931d-da573eb8ecfe;kibana:application:discover:new;application:discover:new",
"content-type": "application/json",
"took-nanos": "17916093875",
"x-elasticsearch-async-id": "FnRUYVdrbElOUUR1VUdCUm1xZ3hHVncdd2RJMUtWU01SQlNmQk1icFgtNGp4QTo1NzU5MTY="
}
These headers should be consistently returned from the endpoint regardless of the status of the underlying query. For context, the is-running
header is important in Kibana to determine whether we should continue polling.
Steps to Reproduce
POST /_query/async?drop_null_columns
{"wait_for_completion_timeout":"200ms","keep_on_completion":true,"keep_alive":"60000ms","query":"FROM filebeat-* METADATA _index\n | EVAL buckets = DATE_TRUNC(5 minute, @timestamp), delay = DELAY(10ms)\n | STATS count = COUNT(*) BY buckets, delay","locale":"en","include_ccs_metadata":true,"filter":{"bool":{"must":[],"filter":[{"range":{"@timestamp":{"format":"strict_date_optional_time","gte":"2025-09-18T21:38:06.992Z","lte":"2025-09-18T21:53:06.992Z"}}}],"should":[],"must_not":[]}}}
// After a few seconds, poll every few seconds
GET /_query/async/{id}?wait_for_completion_timeout=200ms&keep_alive=60000ms&drop_null_columns=true
The latter query returns inconsistent headers.
Logs (if relevant)
No response