Keycloak User Not Found: Debugging Identity Resolution

Guilliano Molaire Guilliano Molaire Updated May 26, 2026 9 min read

Last updated: March 2026

“User not found” is one of the most common support requests for Keycloak deployments. The user insists they have an account. They can see their profile in another system. Their email is correct. But Keycloak cannot find them.

The frustrating part: the user often does exist. The problem is identity resolution — how Keycloak locates a user record based on the credentials or identity information provided. This guide covers every cause of “user not found” errors, with diagnostic queries and solutions for each.

Understanding Identity Resolution in Keycloak

When a user attempts to log in, Keycloak resolves their identity through a series of lookups:

  1. Username lookup: Search the local user store for an exact username match.
  2. Email lookup: If “Login with email” is enabled, search by email address.
  3. User federation lookup: If LDAP or custom User Storage SPIs are configured, query the external store.
  4. Identity provider linking: If the user authenticates via an external IdP, look up the linked account.

A “user not found” error means all applicable lookups failed. The fix depends on which lookup should have succeeded and why it did not.

Cause 1: Case Sensitivity

This is the most common cause. Keycloak stores usernames and emails as-is during registration, but lookup behavior depends on the database collation and Keycloak’s configuration.

The Problem

A user registers with [email protected]. They later try to log in with [email protected]. Depending on your database configuration, this may or may not match.

Diagnosis

Check the user’s stored username and email via the Admin REST API:

# Search by email (case-sensitive by default)
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/[email protected]&exact=true"

# Search without exact match (case-insensitive substring search)
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/users?email=john.smith" | jq .

If the exact search returns nothing but the substring search finds the user, case sensitivity is the issue.

Solution

Option 1: Normalize on registration. Configure a custom authentication flow that lowercases usernames and emails during registration. Use a script authenticator or a custom SPI.

Option 2: Enable case-insensitive lookup. In the Keycloak admin console, navigate to Authentication > Flows and configure the Username Password Form to use case-insensitive lookup. Alternatively, ensure your PostgreSQL database uses a case-insensitive collation for the relevant columns.

Option 3: Fix existing data. Normalize existing usernames in the database:

# Find all users with mixed-case emails
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/users?max=1000" | 
  jq '.[] | select(.email != (.email | ascii_downcase)) | {id, username, email}'

Then update each user:

curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID" 
  -d '{"email": "[email protected]", "username": "[email protected]"}'

Cause 2: Realm Mismatch

Users exist in one realm but attempt to log in against a different realm. This happens more often than you would expect, especially in multi-tenant setups.

The Problem

Your application sends the authentication request to https://keycloak.example.com/realms/production/protocol/openid-connect/auth, but the user was created in the staging realm.

Diagnosis

# Check which realm the user exists in
for realm in $(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms" | jq -r '.[].realm'); do
  result=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
    "https://keycloak.example.com/admin/realms/$realm/[email protected]&exact=true")
  count=$(echo "$result" | jq length)
  if [ "$count" -gt 0 ]; then
    echo "Found in realm: $realm"
    echo "$result" | jq '.[0] | {id, username, email, enabled}'
  fi
done

Solution

  1. Verify the client’s realm configuration. Check the OIDC discovery URL or SAML metadata URL in your application configuration. It must point to the correct realm.

  2. Check the login URL. The realm is embedded in the URL path: /realms/{realm}/protocol/.... A typo or misconfiguration here sends users to the wrong realm.

  3. For multi-tenant applications, ensure your routing logic selects the correct realm based on the tenant identifier. See Multitenancy in Keycloak Using the Organizations Feature for architectural patterns.

Cause 3: LDAP Sync Issues

When Keycloak is federated with LDAP or Active Directory, users may exist in the directory but not be visible to Keycloak due to sync problems.

The Problem

The LDAP user exists in Active Directory, but Keycloak’s periodic sync has not run, the user falls outside the configured search filter, or the connection to LDAP is failing silently.

Diagnosis

Step 1: Check LDAP sync status. In the admin console, navigate to User Federation > [Your LDAP provider] and click Synchronize all users. Check the sync results.

Step 2: Test LDAP connectivity directly.

# Test LDAP search (replace with your LDAP details)
ldapsearch -H ldaps://ldap.company.com -D "cn=keycloak,ou=services,dc=company,dc=com" 
  -w "$LDAP_PASSWORD" -b "ou=users,dc=company,dc=com" 
  "(sAMAccountName=john.smith)"

Step 3: Check the LDAP filter in Keycloak. The User Federation configuration includes a Custom User LDAP Filter. If set, it limits which LDAP users are visible. Common issues:

# Too restrictive filter - excludes the user
(&(objectClass=person)(memberOf=cn=app-users,ou=groups,dc=company,dc=com))

# User might be in a sub-group, not directly in app-users

Step 4: Check the search base. If the Users DN is set to ou=engineering,dc=company,dc=com, users in ou=marketing,dc=company,dc=com will not be found.

Solution

  1. Broaden the Users DN to cover all organizational units, or configure multiple LDAP providers, one per OU.

  2. Fix the Custom User LDAP Filter to include the user. Test the filter with ldapsearch first.

  3. Trigger a manual sync to pull the user into Keycloak’s local cache.

  4. Enable periodic sync with a reasonable interval (every 5-15 minutes for active directories).

  5. Check LDAP connection credentials. The bind DN password may have expired or the service account may be locked. Review Keycloak’s logs for LDAP connection errors:

# Filter Keycloak logs for LDAP errors
grep -i "ldap|federation" /opt/keycloak/data/log/keycloak.log

For comprehensive event analysis, configure audit logging to capture federation events.

Cause 4: Identity Provider Linking

When users authenticate through an external identity provider (Google, Azure AD, Okta), Keycloak links the external identity to a local user account. If this linking fails or has not occurred, the user exists externally but not locally.

The Problem

A user authenticates via Google for the first time. Keycloak’s identity brokering flow should create a local user and link it to the Google identity. But the linking fails because:

  • An account with that email already exists (created through direct registration)
  • The “First Broker Login” flow is misconfigured
  • The email from the IdP does not match the existing account’s email

Diagnosis

# Check if the user exists locally
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/[email protected]" | jq .

# Check federated identities for the user
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/federated-identity" | jq .

Solution

If the user exists but the IdP link is missing:

# Link the identity provider manually
curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/federated-identity/google" 
  -d '{
    "identityProvider": "google",
    "userId": "google-user-id",
    "userName": "[email protected]"
  }'

If the user does not exist and should be auto-created:

Check the First Broker Login flow in Authentication > Flows. The default flow includes:

  1. Review Profile: Asks the user to confirm their profile (can be disabled).
  2. Create User If Unique: Creates a local account if no matching user exists.
  3. Link Existing Account: Attempts to link to an existing account by email.

Common misconfigurations:

  • “Create User If Unique” is disabled
  • “Link Existing Account” is set to require email verification but email is not configured
  • A custom first broker login flow skips the user creation step

See Identity Providers for managed IdP configuration and Attribute Mapping in Keycloak During OIDC Identity Brokering for mapping setup.

Cause 5: Disabled or Locked Accounts

A user account can exist but be inaccessible:

Disabled Account

# Check if the account is enabled
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/[email protected]" | 
  jq '.[0] | {id, username, email, enabled}'

If enabled is false, re-enable it:

curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID" 
  -d '{"enabled": true}'

Brute Force Lockout

If brute force protection is enabled, the user may be temporarily locked:

# Check brute force status
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/attack-detection/brute-force/users/$USER_ID" | jq .

Clear the lockout:

curl -X DELETE -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/attack-detection/brute-force/users/$USER_ID"

Required Actions Blocking Login

Users with pending required actions (like “Verify Email” or “Update Password”) may appear to be “not found” if the application does not handle the redirect to the required action page correctly.

# Check required actions
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID" | 
  jq '.requiredActions'

Cause 6: Username vs Email Lookup

Keycloak can be configured to allow login by username, email, or both. If a user tries to log in with their email but the realm only accepts usernames (or vice versa), the lookup fails.

Diagnosis

Check realm settings:

curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm" | 
  jq '{loginWithEmailAllowed, registrationEmailAsUsername, editUsernameAllowed}'
Setting Effect
loginWithEmailAllowed: true Users can log in with email or username
loginWithEmailAllowed: false Only username is accepted
registrationEmailAsUsername: true Email is used as the username

Solution

If your users expect to log in with email, enable loginWithEmailAllowed:

curl -X PUT -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/myrealm" 
  -d '{"loginWithEmailAllowed": true}'

Cause 7: Client-Level User Restrictions

Users may exist in the realm but be restricted from accessing a specific client. If you have configured client-level role restrictions, users without the required role see an “account not found” or “access denied” error.

Diagnosis

Check if the client has a conditional authentication flow or requires specific roles:

# Check client-level roles assigned to the user
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/role-mappings/clients/$CLIENT_UUID" | jq .

Solution

Assign the required client role:

curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" 
  -H "Content-Type: application/json" 
  "https://keycloak.example.com/admin/realms/myrealm/users/$USER_ID/role-mappings/clients/$CLIENT_UUID" 
  -d '[{"id": "role-uuid", "name": "required-role"}]'

For role-based access control patterns, see Skycloak’s RBAC feature and Understanding RBAC.

Using Event Logs for Diagnosis

Keycloak’s event system records login attempts, including failures. This is often the fastest way to diagnose “user not found” issues.

Enable Login Events

In the admin console, navigate to Realm Settings > Events. Enable Save Login Events and select these event types:

  • LOGIN
  • LOGIN_ERROR
  • REGISTER
  • REGISTER_ERROR
  • IDENTITY_PROVIDER_LOGIN
  • IDENTITY_PROVIDER_LOGIN_ERROR

Query Events via API

# Get recent login errors
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" 
  "https://keycloak.example.com/admin/realms/myrealm/events?type=LOGIN_ERROR&max=20" | 
  jq '.[] | {time: (.time / 1000 | todate), error, userId, ipAddress, details}'

The error field tells you why the login failed:

Error Meaning
user_not_found Username/email lookup returned no results
user_disabled Account exists but is disabled
user_temporarily_disabled Brute force lockout active
invalid_user_credentials User found but password is wrong

For comprehensive audit logging, see Auditing in Keycloak: How to Catch Them All and Skycloak’s Audit Logs feature.

A Systematic Debugging Workflow

When a user reports they cannot log in, follow this sequence:

  1. Get the exact error they see (screenshot or error text).
  2. Identify the realm and client from their login URL.
  3. Search for the user in that realm by both email and username.
  4. Check if the account is enabled and not locked.
  5. Check event logs for the specific login error.
  6. If using LDAP, verify the user exists in the directory and the sync filter includes them.
  7. If using an external IdP, check the federated identity link.
  8. If using client restrictions, verify the user has the required role.

Most “user not found” issues resolve at step 3 (case sensitivity or realm mismatch) or step 6 (LDAP filter).

Preventing User Not Found Issues

  1. Standardize email format at registration: lowercase and trim whitespace.
  2. Enable “Login with email” unless you have a specific reason not to.
  3. Test LDAP filters with ldapsearch before configuring them in Keycloak.
  4. Monitor sync failures with alerts on LDAP federation errors.
  5. Use the SCIM protocol for user provisioning to keep systems in sync.
  6. Document your realm structure so support teams know where to look for users.

Tired of debugging identity resolution issues? Skycloak provides managed Keycloak with built-in user management, monitoring, and support. Check our pricing or review our documentation to learn more.

Guilliano Molaire
Written by Guilliano Molaire Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Ready to simplify your authentication?

Deploy production-ready Keycloak in minutes. Unlimited users, flat pricing, no SSO tax.

© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman