Your Keycloak server is refusing authentication requests from your frontend application because it’s violating the browser’s Same-Origin Policy. This isn’t a Keycloak bug; it’s the browser protecting users from malicious sites.
This error, often seen as Access to fetch at 'YOUR_KEYCLOAK_URL/realms/YOUR_REALM/protocol/openid-connect/token' from origin 'YOUR_FRONTEND_URL' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. means the Keycloak server didn’t explicitly tell your browser that requests from your frontend’s origin are allowed.
Here’s how to fix it, covering the most common causes:
1. Missing or Incorrect CORS Configuration in Keycloak
Keycloak has a dedicated section for CORS. If this is misconfigured, it’s the most likely culprit.
Diagnosis: Log into your Keycloak admin console. Navigate to your realm. In the left-hand menu, go to "Client" and select your frontend application’s client ID. Scroll down to the "Web Origins" setting.
Common Causes & Fixes:
-
Empty "Web Origins": If this field is empty, Keycloak defaults to disallowing all cross-origin requests, which is the most secure default but breaks development setups.
- Fix: Add
*to the "Web Origins" field. This tells Keycloak to allow requests from any origin. For production, you’ll want to be more specific. - Why it works: The
*wildcard explicitly grants permission for any origin to make requests to this client.
- Fix: Add
-
Incorrect Specific Origins: You might have tried to add specific origins but made a typo or missed a protocol/port.
- Fix: Ensure the origins are listed exactly as they appear in your browser’s address bar. For a local development server running on
http://localhost:3000, you must includehttp://localhost:3000. If your frontend is served over HTTPS, you needhttps://your-frontend.com. - Why it works: Keycloak matches the origin of the incoming request against this list. An exact match is required.
- Fix: Ensure the origins are listed exactly as they appear in your browser’s address bar. For a local development server running on
-
Missing
+for Wildcard Subdomains: If you need to allow*.yourdomain.com, you need to explicitly add the wildcard.- Fix: Add
*.yourdomain.comto the "Web Origins" field. - Why it works: This allows any subdomain under
yourdomain.comto make requests.
- Fix: Add
-
Valid Redirect URIsMismatch: While not strictly CORS, this is often confused and can lead to similar redirect failures. The "Web Origins" control which origins can initiate requests, while "Valid Redirect URIs" control where Keycloak can redirect the user after authentication. If these don’t align, your flow breaks.- Fix: Ensure your frontend’s redirect URI (e.g.,
http://localhost:3000/callback) is listed in the "Valid Redirect URIs" for your client in Keycloak. - Why it works: Keycloak only redirects to explicitly authorized URIs to prevent security vulnerabilities.
- Fix: Ensure your frontend’s redirect URI (e.g.,
2. Keycloak Behind a Reverse Proxy (Nginx, Apache, etc.)
If Keycloak is running behind a reverse proxy, the proxy needs to be configured to pass the correct CORS headers. Keycloak might be configured correctly internally, but the proxy strips or overwrites the headers.
Diagnosis:
Use your browser’s developer tools (Network tab) to inspect the response headers from your Keycloak server. Look for Access-Control-Allow-Origin. If it’s missing or incorrect, check your proxy configuration.
Common Causes & Fixes:
-
Proxy Stripping CORS Headers: Some proxy configurations might strip headers they don’t recognize or explicitly disallow them.
- Fix (Nginx Example): Ensure your
locationblock for Keycloak doesn’t have directives that interfere with CORS headers. If you’re usingproxy_hide_header, make sureAccess-Control-Allow-Originisn’t listed. You might need to explicitly add it if Keycloak isn’t setting it correctly.location /auth/ { proxy_pass http://keycloak-internal-address:8080/auth/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Ensure Keycloak's CORS headers are passed through proxy_pass_header Access-Control-Allow-Origin; proxy_pass_header Access-Control-Allow-Methods; proxy_pass_header Access-Control-Allow-Headers; proxy_pass_header Access-Control-Allow-Credentials; } - Why it works:
proxy_pass_headertells Nginx to forward specific headers from the backend (Keycloak) to the client, ensuring the browser receives them.
- Fix (Nginx Example): Ensure your
-
Proxy Adding Its Own Incorrect CORS Headers: The proxy might be configured to add its own CORS headers, which conflict with Keycloak’s.
- Fix (Nginx Example): Remove any
add_headerdirectives for CORS from the proxy configuration that might be overriding Keycloak’s. - Why it works: By removing the proxy’s conflicting headers, you allow Keycloak’s correctly configured CORS headers to be the ones the browser sees.
- Fix (Nginx Example): Remove any
3. Incorrect Access-Control-Allow-Credentials Header
This header is crucial if your authentication involves cookies or credentials. If your frontend sends credentials (like cookies) and Keycloak doesn’t explicitly allow them via CORS, the request will fail.
Diagnosis:
In your browser’s developer tools, look at the response headers from Keycloak for Access-Control-Allow-Credentials. It should be true. Also, check your frontend’s JavaScript code to ensure it’s configured to send credentials with requests (e.g., withCredentials: true in axios).
Common Causes & Fixes:
-
Access-Control-Allow-Credentialsnot set totrue: If your frontend needs to send cookies or authorization headers automatically managed by the browser.- Fix: In Keycloak’s realm settings, under "HTTP" -> "CORS", ensure "Access-Control-Allow-Credentials" is enabled. If you’re using specific origins in "Web Origins", you cannot use
*forAccess-Control-Allow-OriginwhenAccess-Control-Allow-Credentialsistrue. You must list specific origins. - Why it works: This header explicitly tells the browser that the server permits credentials (like cookies) to be sent with cross-origin requests.
- Fix: In Keycloak’s realm settings, under "HTTP" -> "CORS", ensure "Access-Control-Allow-Credentials" is enabled. If you’re using specific origins in "Web Origins", you cannot use
-
Access-Control-Allow-Originis*andAccess-Control-Allow-Credentialsistrue: Browsers disallow this combination for security reasons.- Fix: Replace
*in your "Web Origins" with your specific frontend origin (e.g.,http://localhost:3000). - Why it works: By specifying the origin, you remove the security risk associated with allowing credentials from any arbitrary source.
- Fix: Replace
4. Keycloak Theme/Customization Issues
If you’ve heavily customized Keycloak’s themes or added custom SPIs, there’s a small chance your customizations are interfering with the CORS headers being set.
Diagnosis: Temporarily revert to a default Keycloak theme. If the CORS errors disappear, your custom theme is the issue.
Fix: Review your custom theme’s JavaScript or any custom SPIs that might be intercepting or modifying responses. Ensure they are not stripping or incorrectly setting CORS headers.
Why it works: A clean, default configuration eliminates custom code as a variable, helping isolate the problem to either Keycloak’s core settings or external factors.
5. Browser Cache or Extensions
Sometimes, the browser itself can be the culprit due to cached responses or interfering extensions.
Diagnosis: Try accessing your application in an incognito/private browsing window. If it works there, your browser cache or extensions are likely the issue.
Fix: Clear your browser’s cache and cookies. Disable browser extensions one by one to identify if one is interfering with CORS requests.
Why it works: A clean browser session starts with fresh state, bypassing any stale cached data or problematic extension logic.
After applying these fixes, the next error you’ll likely encounter (if not already present) is a 400 Bad Request or a redirect loop if your Valid Redirect URIs are still not correctly configured.