TL;DR: The cluster is up and reachable, but your credentials are wrong. Check the username/password (or API key) you pass to the client; in v8 it is basic_auth=(user, password), not http_auth.

```text
elasticsearch.exceptions.AuthenticationException: AuthenticationException(401, 'security_exception', 'unable to authenticate user [elastic] for REST request [/]')
```

## Fix it

1. Verify the credentials outside Python: curl -u elastic:[password] [host]:9200. Expected: cluster info JSON. A 401 here means the password itself is wrong.
2. In v8 code use basic_auth: Elasticsearch(hosts, basic_auth=('elastic', [password])). Expected: no more 401.
3. If you use API keys, pass the api_key argument as a tuple of your API id and API key. Expected: authenticated.
4. For the elastic superuser password set at install, check your install notes or reset it; do not guess repeatedly (it can lock the account).

## When this applies
- The error is 401 security_exception on REST calls.

## When it doesn't
- Connection refused/timeout: the cluster is not reachable at all.
- 403 security_exception: authenticated but the role lacks the privilege.

## Compatibility
- elasticsearch-py 7.x (http_auth) and 8.x (basic_auth).

## Why it happens
X-Pack security rejects unknown or wrong credentials at the REST layer before any index logic runs, so every call 401s identically.

## Edge cases
- Special characters in passwords break shell curl but are fine inside Python strings; test accordingly.
- API keys encode the id and key as a tuple in v8; passing a single string 401s.
