๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGorg.springframework.security.oauth2.core.OAuth2AuthenticationException: [authorization_request_not_found] ClientRegistration not found with identifier: google at org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository.loadAuthorizationRequest(HttpSessionOAuth2AuthorizationRequestRepository.java:100)

โšก Quick Fix Works 80% of the time

Ensure your reverse proxy passes the correct headers, or use a cookie-based AuthorizationRequestRepository.

@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.oauth2Login(Customizer.withDefaults()); // If behind Nginx, ensure proxy_set_header X-Forwarded-Proto $scheme; is set return http.build(); }

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

When a user clicks 'Login with Google', Spring Security generates an authorization request and saves it in the HTTP session. It then redirects the user to Google. When Google redirects back to your app, Spring looks for that saved request to verify the state. If it's missing (due to session expiration, blocked cookies, or domain mismatch), it throws this error.

The HITEC City Parking Spot Analogy:

It's like leaving a coat at a coat check. You get a ticket. When you come back to claim it, the attendant says, 'I don't see any record of this coat.' If you lose the ticket (cookie/session), or the attendant shifts, you can't prove you left it there.

๐Ÿ” How to Reproduce Confirm this is your error

Start an OAuth2 login flow. When redirected to Google, clear your browser cookies for your local app. Complete the Google login. When the callback hits your app, it will fail.

๐Ÿ› ๏ธ Solutions (5 Ways to Fix)

Solution 1โœ“ Most common cause

Fix Reverse Proxy Headers (Nginx/Traefik)

๐Ÿ‘‰ Use this if your app works locally but fails in production behind a load balancer.

Spring Security stores the OAuth2 state in the session, which is tied to the domain/protocol. If the proxy terminates SSL but doesn't tell Spring, Spring might generate HTTP URLs for the callback, breaking the state.

# Nginx configuration location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; # CRITICAL FOR OAUTH2 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
Solution 2

Use a Cookie-based Repository

๐Ÿ‘‰ Use this if your sessions are failing due to distributed environments or strict firewalls.

Instead of storing the state in the server session, store it in a short-lived cookie in the user's browser.

import org.springframework.security.oauth2.client.web.CookieOAuth2AuthorizationRequestRepository; @Bean public SecurityFilterChain filterChain(HttpSecurity http, OAuth2AuthorizationRequestRepository<OAuth2AuthorizationRequest> authRequestRepo) throws Exception { http.oauth2Login(oauth -> oauth .authorizationEndpoint(auth -> auth .authorizationRequestRepository(authRequestRepo) // Wire the cookie-based repo ) ); return http.build(); } @Bean public OAuth2AuthorizationRequestRepository<OAuth2AuthorizationRequest> authRequestRepository() { return new CookieOAuth2AuthorizationRequestRepository(); // Cookie-based, not session-based }
Solution 3

Ensure browser cookies aren't blocked

๐Ÿ‘‰ Use this if testing in a strict corporate environment or old browser.

If the user's browser blocks third-party cookies or SameSite=Strict cookies, the session cookie is lost during the redirect to Google and back.

// Ensure Spring Session cookie is set to SameSite=Lax // (Usually default in Spring Boot, but check your server.servlet.session.cookie.same-site property)
Solution 4

Fix Server Clock / Time Sync

๐Ÿ‘‰ Use this if servers are randomly losing state.

If your server clock is out of sync, the session or cookie might expire instantly because it thinks the timestamp is in the past.

# Sync server time sudo ntpdate ntp.ubuntu.com
Solution 5

Check server.servlet.context-path

๐Ÿ‘‰ Use this if your app runs under a sub-path (e.g., /api).

The OAuth2 callback URL must exactly match the path registered in Google Console. If the context path is missing, the state mismatch occurs.

# application.properties server.servlet.context-path=/api # Google Console Redirect URI: https://localhost:8080/api/login/oauth2/code/google

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Uses HttpSessionOAuth2AuthorizationRequestRepository by default.

Spring Boot 3.x

Identical default, but better logging for reverse proxy misconfigurations.

๐Ÿ›ก๏ธ How to Prevent This Next Time

Always use `X-Forwarded-Proto` in reverse proxies. Use cookie-based OAuth2 state storage for microservices architectures.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase