This happens when:
The app (OpenSearch in this case) replays the same authorization_code to the /token endpoint multiple times, or
The redirect URI / callback URL mismatches the one registered in Entra ID, invalidating the redemption, or
A network proxy, caching layer, or plugin bug causes the same code to be “retried.”
Since you said it used to work fine, and broke suddenly, this strongly points to session or configuration desync between OpenSearch and Entra ID.
Step 1: Clear OpenSearch SSO session cache
Stop OpenSearch.
Delete the SSO session cache or temporary tokens from your OpenSearch data directory.
If you’re using the OpenSearch Security Plugin, remove any cached config or auth_token state (usually in /usr/share/opensearch/plugins/opensearch-security/).
Then restart:
sudo systemctl restart opensearch
This ensures it requests a new authorization code.
Step 2: Verify redirect URI in Entra ID
In Azure Portal → Entra ID → App registrations → [Your OpenSearch App] → Authentication
✅ Make sure the redirect URI matches exactly what OpenSearch is using, e.g.:
https://opensearch.yourdomain.com/_opendistro/_security/sso/auth/openid
Common mistakes:
Missing /openid
Using http instead of https
Trailing /
Wrong hostname (proxy vs internal FQDN)
If you changed OpenSearch URLs recently, update it here and save.
Step 3: Check time synchronization
Run:
timedatectl status
Ensure:
System clock synchronized: yes
NTP service: active
If time drift > 5 min, fix it immediately:
sudo timedatectl set-ntp true
Step 4: Validate OpenSearch OIDC config
Check your OpenSearch configuration file (often config/opensearch.yml):
opendistro_security.openid.connect_url: "https://login.microsoftonline.com/<tenant_id>/v2.0/.well-known/openid-configuration"
opendistro_security.openid.client_id: "<client_id>"
opendistro_security.openid.client_secret: "<client_secret>"
opendistro_security.openid.redirect_uri: "https://opensearch.yourdomain.com/_opendistro/_security/sso/auth/openid"
opendistro_security.openid.scope: "openid profile email"
Re-check the tenant ID, client ID, and secret. If you regenerated the secret recently, restart OpenSearch after updating it.
Step 5: Test manually with curl
To isolate the issue:
Use browser → authenticate → capture code parameter in redirect URL.
Run manually:
curl -X POST https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token \
-d "client_id=<client_id>" \
-d "scope=openid profile email" \
-d "grant_type=authorization_code" \
-d "code=<auth_code_here>" \
-d "redirect_uri=https://opensearch.yourdomain.com/_opendistro/_security/sso/auth/openid" \
-d "client_secret=<client_secret>"
You should get an access token. If you get the same error immediately → Entra is rejecting the code (already used or expired). If it works → OpenSearch is reusing the code somewhere internally.
Step 1: Clear OpenSearch SSO session cache
Stop OpenSearch.
Delete the SSO session cache or temporary tokens from your OpenSearch data directory.
If you’re using the OpenSearch Security Plugin, remove any cached config or auth_token state (usually in /usr/share/opensearch/plugins/opensearch-security/).
Then restart:
sudo systemctl restart opensearch
This ensures it requests a new authorization code.
Step 2: Verify redirect URI in Entra ID
In Azure Portal → Entra ID → App registrations → [Your OpenSearch App] → Authentication
✅ Make sure the redirect URI matches exactly what OpenSearch is using, e.g.:
https:
Common mistakes:
Missing /openid
Using http instead of https
Trailing /
Wrong hostname (proxy vs internal FQDN)
If you changed OpenSearch URLs recently, update it here and save.
Step 3: Check time synchronization
Run:
timedatectl status
Ensure:
System clock synchronized:
If time drift > 5 min, fix it immediately:
sudo timedatectl set-ntp
Step 4: Validate OpenSearch OIDC config
Check your OpenSearch configuration file (often config/opensearch.yml):
opendistro_security.openid.connect_url:
Re-check the tenant ID, client ID, and secret.
If you regenerated the secret recently, restart OpenSearch after updating it.
Step 5: Test manually with curl
To isolate the issue:
Use browser → authenticate → capture code parameter in redirect URL.
Run manually:
curl -X POST https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token \
-d
You should get an access token.
If you get the same error immediately → Entra is rejecting the code (already used or expired).
If it works → OpenSearch is reusing the code somewhere internally.