Reindex request failure causes error parsing exception

Elasticsearch version and Elasticsearch Java client version: 8.13.4

Hi!
When destination index is read only, reindex request expectedly fail, but Elastic Java client is not able to parse the failure response with the following exception:

co.elastic.clients.transport.TransportException: node: http://localhost:9200/, status: 403, [es/reindex] Failed to decode error response, check exception cause for additional details
	at co.elastic.clients.transport.ElasticsearchTransportBase.getApiResponse(ElasticsearchTransportBase.java:357) ~[elasticsearch-java-8.13.4.jar:?]
	at co.elastic.clients.transport.ElasticsearchTransportBase.lambda$performRequestAsync$0(ElasticsearchTransportBase.java:211) ~[elasticsearch-java-8.13.4.jar:?]
	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) ~[?:?]
	at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) ~[?:?]
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[?:?]
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179) ~[?:?]
	at co.elastic.clients.transport.rest_client.RestClientHttpClient$1.onSuccess(RestClientHttpClient.java:115) ~[elasticsearch-java-8.13.4.jar:?]
	at org.elasticsearch.client.RestClient$FailureTrackingResponseListener.onSuccess(RestClient.java:680) ~[elasticsearch-rest-client-8.13.4.jar:8.13.4]
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:403) ~[elasticsearch-rest-client-8.13.4.jar:8.13.4]
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:397) ~[elasticsearch-rest-client-8.13.4.jar:8.13.4]
	at org.apache.http.concurrent.BasicFuture.completed(BasicFuture.java:122) ~[httpcore-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:182) ~[httpasyncclient-4.1.5.jar:4.1.5]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.processResponse(HttpAsyncRequestExecutor.java:448) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.inputReady(HttpAsyncRequestExecutor.java:338) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:265) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:87) ~[httpasyncclient-4.1.5.jar:4.1.5]
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:40) ~[httpasyncclient-4.1.5.jar:4.1.5]
	at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591) ~[httpcore-nio-4.4.16.jar:4.4.16]
	... 1 more
Caused by: co.elastic.clients.json.UnexpectedJsonEventException: Unexpected JSON event 'VALUE_NUMBER' instead of 'KEY_NAME'
	at co.elastic.clients.json.JsonpUtils.expectEvent(JsonpUtils.java:106) ~[elasticsearch-java-8.13.4.jar:?]
	at co.elastic.clients.transport.endpoints.EndpointBase$1.deserialize(EndpointBase.java:150) ~[elasticsearch-java-8.13.4.jar:?]
	at co.elastic.clients.transport.endpoints.EndpointBase$1.deserialize(EndpointBase.java:144) ~[elasticsearch-java-8.13.4.jar:?]
	at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:77) ~[elasticsearch-java-8.13.4.jar:?]
	at co.elastic.clients.transport.ElasticsearchTransportBase.getApiResponse(ElasticsearchTransportBase.java:343) ~[elasticsearch-java-8.13.4.jar:?]
	at co.elastic.clients.transport.ElasticsearchTransportBase.lambda$performRequestAsync$0(ElasticsearchTransportBase.java:211) ~[elasticsearch-java-8.13.4.jar:?]
	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) ~[?:?]
	at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) ~[?:?]
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[?:?]
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179) ~[?:?]
	at co.elastic.clients.transport.rest_client.RestClientHttpClient$1.onSuccess(RestClientHttpClient.java:115) ~[elasticsearch-java-8.13.4.jar:?]
	at org.elasticsearch.client.RestClient$FailureTrackingResponseListener.onSuccess(RestClient.java:680) ~[elasticsearch-rest-client-8.13.4.jar:8.13.4]
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:403) ~[elasticsearch-rest-client-8.13.4.jar:8.13.4]
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:397) ~[elasticsearch-rest-client-8.13.4.jar:8.13.4]
	at org.apache.http.concurrent.BasicFuture.completed(BasicFuture.java:122) ~[httpcore-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:182) ~[httpasyncclient-4.1.5.jar:4.1.5]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.processResponse(HttpAsyncRequestExecutor.java:448) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.inputReady(HttpAsyncRequestExecutor.java:338) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:265) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:87) ~[httpasyncclient-4.1.5.jar:4.1.5]
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:40) ~[httpasyncclient-4.1.5.jar:4.1.5]
	at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) ~[httpcore-nio-4.4.16.jar:4.4.16]
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591) ~[httpcore-nio-4.4.16.jar:4.4.16]

When I try with Postman, the response looks like this:

{
    "took": 215,
    "timed_out": false,
    "total": 6535,
    "updated": 0,
    "created": 0,
    "deleted": 0,
    "batches": 1,
    "version_conflicts": 0,
    "noops": 0,
    "retries": {
        "bulk": 0,
        "search": 0
    },
    "throttled_millis": 0,
    "requests_per_second": -1.0,
    "throttled_until_millis": 0,
    "failures": [
        {
            "index": "<name>",
            "id": "2251799813689457",
            "cause": {
                "type": "cluster_block_exception",
                "reason": "index [<name>] blocked by: [FORBIDDEN/5/index read-only (api)];"
            },
            "status": 403
        },
        <..>
]
}

As a result of parsing error I can't see the proper error message in my application. Does this sound like a bug?

Hello!
Yes it does sound like a bug ^^"
The specification for the response class seems wrong, and so is the generated java code: in failures, type is a required field outside cause, while here it's found inside cause. Will fix this asap and regenerate the java code!
Unfortunately version 8.13 is no longer supported for patches so the minimum version that will be updated is 8.16.

1 Like

@ltrotta Thank you for checking this!
Is there some bug issue that I can follow?

You can create a new one in the github repo. Thanks!

1 Like