Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

Read more

Common OpenID Connect (OIDC) Authentication Errors in Elasticsearch

Elasticsearch supports OpenID Connect (OIDC) as an authentication realm, allowing users to authenticate through external identity providers like Keycloak, Azure Entra ID, and Okta. Misconfigurations at any layer - Elasticsearch realm settings, Kibana provider config, TLS trust, or the identity provider itself - produce errors that can be difficult to trace.

OIDC Realm Configuration in elasticsearch.yml

The OIDC realm is defined under xpack.security.authc.realms.oidc.<realm-name> in elasticsearch.yml. A minimal configuration requires these settings:

xpack.security.authc.realms.oidc.oidc1:
  order: 2
  rp.client_id: "elasticsearch"
  rp.response_type: "code"
  rp.redirect_uri: "https://kibana.example.com/api/security/oidc/callback"
  op.issuer: "https://idp.example.com/realms/main"
  op.authorization_endpoint: "https://idp.example.com/realms/main/protocol/openid-connect/auth"
  op.token_endpoint: "https://idp.example.com/realms/main/protocol/openid-connect/token"
  op.jwkset_path: "https://idp.example.com/realms/main/protocol/openid-connect/certs"
  claims.principal: "email"

The op.jwkset_path accepts an HTTPS URL or a local file path. With a URL, Elasticsearch fetches the JWK set periodically. With a local path, you must update the file when the provider rotates signing keys. A NoSuchFileException on startup means the path is wrong or the file is missing from the config directory.

The client secret is stored in the Elasticsearch keystore, not in elasticsearch.yml: bin/elasticsearch-keystore add xpack.security.authc.realms.oidc.oidc1.rp.client_secret. Omitting this causes token exchange failures.

Token Validation Failures

Most OIDC authentication errors trace back to ID token validation. Elasticsearch validates the token's issuer, audience, expiration, and signature. Each check can fail independently.

Issuer mismatch occurs when the iss claim in the ID token does not exactly match the op.issuer value configured in the realm. Trailing slashes matter. If your provider returns https://idp.example.com/realms/main but you configured https://idp.example.com/realms/main/, validation fails. Copy the issuer value directly from your provider's .well-known/openid-configuration endpoint.

Audience mismatch happens when the aud claim in the ID token does not contain the rp.client_id value. Some providers include multiple audiences when additional resources are configured. Verify that the client ID registered with the provider matches exactly what is set in rp.client_id.

Clock skew causes token rejection when the Elasticsearch node's system clock differs from the identity provider's clock. Tokens have iat (issued at) and exp (expiration) claims validated against local time. Run NTP on all Elasticsearch nodes and the identity provider host. Elasticsearch allows a small amount of clock skew by default, but differences beyond a few seconds will cause expired token errors even for freshly issued tokens.

Expired tokens appear when the token's exp claim is in the past. This usually points to a slow redirect flow where the user takes too long to complete login.

TLS and Certificate Issues

Elasticsearch must trust the certificate presented by the identity provider when fetching the JWK set, exchanging authorization codes, or calling the userinfo endpoint. If the provider uses a certificate signed by an internal CA, configure trust in the realm:

xpack.security.authc.realms.oidc.oidc1:
  ssl.certificate_authorities: ["/etc/elasticsearch/oidc/company-ca.pem"]

Without this, expect SSLHandshakeException or PKIX path building failed errors. Self-signed certificates require the same treatment. On Elastic Cloud, custom CA certificates must be uploaded as part of a custom bundle. Certificate expiration on the provider side also causes sudden failures after months of working configuration.

Kibana Configuration and Claim-to-Role Mapping

Kibana requires its own OIDC provider configuration in kibana.yml:

xpack.security.authc.providers:
  oidc.oidc1:
    order: 0
    realm: "oidc1"

The realm value must match the realm name defined in elasticsearch.yml. A mismatch produces a generic authentication failure with no clear error in Kibana's UI.

Role mapping ties OIDC claims to Elasticsearch roles. Create role mappings using the API or role_mapping.yml. For example, mapping a groups claim to Elasticsearch roles:

PUT /_security/role_mapping/oidc_kibana_users
{
  "roles": ["kibana_admin"],
  "enabled": true,
  "rules": {
    "field": { "realm.name": "oidc1" }
  }
}

For finer control, use the claims.groups setting in the realm config to extract group membership from the ID token, then reference groups in role mapping rules. If users authenticate but have no permissions, check the role mapping first. When standard logs do not reveal the root cause, enable TRACE-level logging:

PUT /_cluster/settings
{
  "transient": {
    "logger.org.elasticsearch.xpack.security.authc.oidc": "TRACE"
  }
}

TRACE output includes authorization callback parameters, token exchange requests, ID token claims, and JWK set contents. This exposes exactly where validation fails. Disable it after debugging by setting the logger back to INFO - TRACE logs sensitive tokens and secrets.

Provider-Specific Notes

Keycloak uses realm-scoped endpoints. The issuer URL includes the realm path (e.g., https://keycloak.example.com/realms/myrealm). A common mistake is omitting the realm segment. Keycloak also rotates signing keys periodically. If you use a local op.jwkset_path file, stale keys cause signature validation failures after rotation.

Azure Entra ID (formerly Azure AD) can include a large number of groups in the token's groups claim. When a user belongs to many groups, Azure switches to an "overage" indicator instead of embedding groups directly. To avoid this, configure the app registration in Azure to emit only groups assigned to the application via Token configuration > Edit groups claim > Groups assigned to the application. The issuer URL format for Azure is typically https://login.microsoftonline.com/{tenant-id}/v2.0.

Okta requires setting the Login redirect URI to https://kibana.example.com/api/security/oidc/callback in the Okta application configuration. Okta's issuer URL format is https://{your-okta-domain}/oauth2/default when using the default authorization server. Using the org authorization server (https://{your-okta-domain}) instead produces a different issuer value and causes mismatch errors.

Pulse - Elasticsearch Operations Done Right

Pulse can solve your Elasticsearch issues

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.