Index status / Report unreadable cluster health responses - #9478
Open
juanluisrp wants to merge 2 commits into
Open
Index status / Report unreadable cluster health responses#9478juanluisrp wants to merge 2 commits into
juanluisrp wants to merge 2 commits into
Conversation
EsServerStatusChecker reads the cluster health through the typed Elasticsearch client. That client only decodes the health response of the server version it is built for: 8.19 requires unassigned_primary_shards, a property added to _cluster/health in Elasticsearch 8.16. Against an older server the call fails with a transport error although the request returned a 200. The catch all then sets the state to uninitialized and the catalogue reports "Unable to revive connection to http://host:9200", which points at connectivity while the server is in fact reachable and search keeps working through the search proxy. Read the status with the low level client when the typed client can not decode the response, so the reported state matches the state of the cluster. When that fails too, report the decoding failure with a message pointing at the version of the index server instead of the connection. The decoding failure is logged once, the check runs every five seconds by default.
The version of the index server is only visible in the site information page. When it is not the version the Elasticsearch client is built for, the failures show up somewhere else entirely, as a response which can not be decoded or as a query the server rejects, and nothing points at the version of the server. Compare the major version of the server with the version of the client once the server can be reached, and report a difference once. The version is read again on the next run when the server can not be reached, so a catalogue started before its index server still reports it.
juanluisrp
marked this pull request as draft
August 14, 2026 10:47
juanluisrp
marked this pull request as ready for review
August 14, 2026 12:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Index status / Report unreadable cluster health responses
Follow up of #9477.
Problem
EsServerStatusCheckerreads the cluster health through the typed Elasticsearch client:The typed client only decodes the health response of the server version it is built for. The client bundled since 4.4.10 (8.19.13) has
unassigned_primary_shardsas a required property of the health response, and that property was only added to_cluster/healthin Elasticsearch 8.16. Against an older server the call fails with:The request succeeded (
status: 200), only the decoding failed, but the singlecatch (Exception e)in the checker turns everything into:So the catalogue permanently displays a connection banner while the server is reachable. The message sends the administrator looking at the network, the firewall and CORS instead of at the version of the index server.
Reading the cluster health (first commit)
EsRestClient.getServerStatus()falls back to a low levelGET /_cluster/healthwhen the typed client can not decode the response, and reads thestatusproperty from the raw JSON. The reported state then matches the state of the cluster. The fallback uses the sameRestClientinstance that backs the typed transport, so thees.username/es.passwordcredentials and the https settings are the ones already configured.es.index.checker.interval), and the message names the client version and points at the compatibility of the index server. It is logged as an error because the default log configuration only logs errors forgeonetwork.index.EsServerStatusCheckerreports the decoding failure separately from a connection failure, again pointing at the version of the index server. The original error is kept as a suppressed exception.This does not add support for unsupported Elasticsearch versions, it only makes the index status and the log say what is actually wrong.
Reporting the version of the index server (second commit)
The version of the server is only visible in the site information page, so nothing tells an administrator that the server is not the one this GeoNetwork is built for.
EsServerStatusCheckernow compares the major version of the server with the version of the client once the server can be reached, and reports a difference once:The version is read again on the next run when the server can not be reached, so a catalogue started before its index server still reports it. Nothing is logged when the versions match, and the state of the index is not changed by this check.
Tests
EsServerStatusCheckerTestcovers the status branches (the cluster status is reported as is, a connection failure is still reported asuninitializedwith the "Unable to revive connection" message, a response the client can not decode is reported with a message pointing at the server version) and the version check (reported for another major version, silent for the version of the client and for a version which can not be parsed, read once, read again when the server can not be reached).The
indexmodule had no test sources yet,junitis inherited from the root pom so no dependency change was needed.Verified against Elasticsearch 7.17.15
Before, the home page shows the banner of #9477 and
/api/site/index/statusreturns:{"id":"index","state":{"id":"uninitialized", ...}, "message":"Unable to revive connection to http://localhost:9200. Error is node: http://localhost:9200/, status: 200, [es/cluster.health] Failed to decode response"}After, no banner and the real state of the cluster:
{"id":"index","state":{"id":"yellow", ...},"message":"Index status is yellow. Check index server log."}with a single line in the log:
Searching still fails on that server, with the error of the incompatibility that is really there (
No mapping found for [createDate] in order to sort on), instead of a connection error on the home page.The version check was verified the same way: against 7.17.15 the message above is logged once at startup, against 8.19.13 nothing is logged.
Checked with and without credentials on a 7.17.15 server with
xpack.security.enabled=true: the fallback authenticates like any other call, and a missing password is still reported as before,missing authentication credentials for REST request [/_cluster/health].Checklist
mvn -pl index testpasses (8 tests)