Delete By Query deserialization will not account for search failures
Maintainers usually reply within 1 day
@l-trotta is already working on this.
Since Oct 2, 2026.
Assessment
This issue has not been assessed yet.
Description
Java API client version
8.14.3
Java version
21
Elasticsearch Version
8.19.11
Problem description
Delete by query's response field has a section for failures that is strictly typed as BulkIndexByScrollFailure. However, in the DeleteByQueryResponse that upstream Elasticsearch can return, the failures list is a union of search failures and indexing failures, and the search failures has a different serialization format than the indexing failures (ES9, ES8). Specifically, search failures put the error under reason, and the bulk failures put the error under cause. The result is that if a search failure is serialized by the server, the client fails to deserialize into a DeleteByQueryResponse correctly unless the default deserializer is overridden accordingly.
Reproducing this is challenging in an isolated case because it requires actually reproducing a search failure that serializes this way. The following is contrived, but can sometimes show the issue if given enough attempts - it tries to specifically close the index under deletion in the middle of one of the scroll iterations of a delete by query job.
ElasticsearchClient client = <create client here>;
String prefix = "dbq-search-failure-" + UUID.randomUUID();
String available = prefix + "-available";
String disappearing = prefix + "-disappearing";
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
for (String index : List.of(available, disappearing)) {
client.indices().create(request -> request.index(index)
.settings(settings -> settings.numberOfShards("1").numberOfReplicas("0")));
}
// Sorting keeps the first batches on the available index, avoiding a bulk write failure when the
// other index closes. Its scroll context still participates, so a later scroll has a search failure.
for (int position = 0; position < 5; position++) {
String id = Integer.toString(position);
Map<String, Integer> document = Map.of("position", position);
client.index(request -> request.index(available).id(id).document(document));
}
client.index(request -> request.index(disappearing).id("last").document(Map.of("position", 100)));
client.indices().refresh(request -> request.index(available, disappearing));
Future<DeleteByQueryResponse> deletion = executor.submit(() -> client.deleteByQuery(request -> request
.index(available, disappearing)
.query(query -> query.matchAll(all -> all))
.sort("position:asc")
.scrollSize(1L)
.scroll(scroll -> scroll.time("1m"))
.requestsPerSecond(0.1f)));
// The first deletion proves the initial search succeeded and both scroll contexts were created.
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(15);
while (client.exists(request -> request.index(available).id("0")).value()) {
if (System.nanoTime() >= deadline) {
throw new AssertionError("Delete-by-query did not finish its first batch");
}
Thread.sleep(50);
}
client.indices().close(request -> request.index(disappearing));
try {
// Expected: a result with failures[0].reason.type == search_context_missing_exception.
// Actual: the generated client models every failure as BulkIndexByScrollFailure.
return deletion.get(45, TimeUnit.SECONDS);
} catch (ExecutionException failure) {
if (failure.getCause() instanceof Exception cause) {
throw cause;
}
throw failure;
}
} finally {
executor.shutdownNow();
client.indices().delete(request -> request.index(available, disappearing).ignoreUnavailable(true));
}
- Dominant language
- Java
- Stars
- 524
- Forks
- 299
- Avg merge
- 16m
- Merged PRs (30d)
- 13
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from elastic/elasticsearch-java
-
Nested index settings that do not end up deserialized in otherSettings leads to requiring properties on parent JSON nodesPossibly taken @l-trotta claimed this 3 days ago. OpenArea: Specification Category: Bug
Difficulty 4/5 3-5 days Newbie friendliness 48/100
elastic/elasticsearch-java#1347 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
-
RestClientTransport sends bulk bodies as one HTTP chunk / TLS record / syscall per NDJSON buffer, burning ~45x the reactor CPU of the HLRCPossibly taken @l-trotta claimed this 19 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 72/100
elastic/elasticsearch-java#1339 · 5 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 45/100
elastic/elasticsearch-java#1212 · 8 comments ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
elastic/elasticsearch-java#1165 · 5 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
elastic/elasticsearch-java#1083 · 2 comments ·
Maintainers usually reply within 1 day
All issues in elastic/elasticsearch-java
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
bancolombia/scaffold-clean-architecture#1002 ·
Maintainers usually reply within 1 day
-
CalendarEventAttendance/get returns eventAttendanceStatus while the doc says attendanceStatusPossibly taken @chibenwa claimed this today. Openbug claude
Difficulty 1/5 Under an hour Newbie friendliness 90/100
linagora/tmail-backend#2697 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
apache/skywalking#14120 ·
Maintainers usually reply within 1 day
-
[BUG] Case-insensitive search suggestions miss items when the JVM default locale is TurkishPossibly taken @thswlsqls claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
HMCL-dev/HMCL#6943 · 1 comment ·
Maintainers usually reply within 1 day