Elasticsearch "unable to authenticate user" (security_exception) in CI
The client did send credentials, but Elasticsearch rejected them: the password does not match, the built-in user was never assigned a password, or the security index has not finished initializing. The request fails with 401 and "unable to authenticate user".
What this error means
Requests return HTTP 401 with "unable to authenticate user [elastic] for REST request". The client is passing a username and password, but the pair is not accepted.
{"error":{"root_cause":[{"type":"security_exception","reason":"unable to authenticate
user [elastic] for REST request [/_cluster/health]"}],"type":"security_exception"},"status":401}Common causes
The password does not match
The client sends a password that differs from the one the node was started with, so authentication fails.
ELASTIC_PASSWORD was never set
Without ELASTIC_PASSWORD, the built-in elastic user has no known password, so any supplied one is rejected.
How to fix it
Set a known password and use it
- Set
ELASTIC_PASSWORDon the service container to a fixed value. - Pass the same username and password from every client and curl call.
- Wait for the cluster to be ready before authenticating, since the security index initializes on startup.
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
env:
discovery.type: single-node
ELASTIC_PASSWORD: test-passwordWait for the security index before authenticating
Poll cluster health first; a 401 immediately after startup can simply mean the security index is not ready yet.
until curl -su elastic:test-password "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=5s" \
| grep -q '"status"'; do sleep 2; doneHow to prevent it
- Set
ELASTIC_PASSWORDto a fixed value in the workflow, not a per-run secret that can drift. - Use the same credentials in the healthcheck and the tests.
- Wait for yellow before the first authenticated request.