Prompt
OAuth login keeps failing on my callback URL. How do I debug it?
Latest observation
Here’s a practical way to debug an OAuth callback failure.
1) Confirm the exact error
Start by capturing the full callback URL your app receives, including query parameters or fragment. Common parameters:
codestateerrorerror_description
If you see:
error=redirect_uri_mismatch→ callback/redirect URL doesn’t exactly match provider config.error=access_denied→ user denied consent.error=invalid_state/ CSRF-style error → state mismatch or session/cookie issue.error=invalid_grant→ code expired, reused, or wrong client/redirect URI used during token exchange.
2) Verify redirect URI matching
OAuth providers usually require an exact match between:
- the redirect URI used in the authorization request, and
- the URI registered in the provider dashboard.
Check:
- scheme:
httpvshttps - domain/subdomain
- port
- path
- trailing slash
- URL encoding
Example mismatch:
- registered:
https://example.com/auth/callback - sent:
https://example.com/auth/callback/
3) Check the callback route is reachable
Make sure your app can actually receive the provider’s redirect:
- Is the route deployed?
- Does it return 200 or the expected handler response?
- Any reverse proxy/load balancer rewriting the path?
- Is HTTPS termination correct?
- Are you accidentally redirecting away before processing the
code?
4) Inspect state/session handling
If your flow uses state, the callback must still have access to the original session.
Common issues:
- Session cookie not set before redirect
- Cookie
SameSiteblocks it Securecookie over HTTP- Different domains between login start and callback
- Multiple app instances without shared session store
For browser-based flows, SameSite=Lax is often needed; for some setups SameSite=None; Secure is required.
5) Check the token exchange request
After callback, your server exchanges the authorization code for tokens. Debug:
- Are you sending the same
redirect_uriin the token request as in the authorization request? - Is the
client_idcorrect? - Is
client_secretcorrect? - Is the
codebeing used only once? - Is the code expired?
Many providers return a useful JSON error here.
6) Log the full OAuth flow
Add logs for:
- authorization request URL you send
- callback query parameters
- token exchange request payload
- token response/error
Be careful not to log secrets or full tokens in production. Redact:
client_secret- access tokens
- refresh tokens
7) Test with a known-good minimal setup
Try:
- a local/dev environment with a simple callback endpoint
- a provider’s documented sample app
- a public tunnel like ngrok if local callback URLs are required
This helps isolate whether the issue is your app, your infrastructure, or the provider config.
8) Look for browser/cookie issues
If the callback depends on cookies/session:
- Open devtools → Application/Storage → Cookies
- Check whether the session cookie is present on the initial login and callback
- Check SameSite/Secure/Domain attributes
- Try in a private window to avoid stale state
9) Compare provider settings vs request parameters
Double-check:
- Authorized redirect URIs
- Allowed origins / JavaScript origins (for SPA flows)
- Scopes
- Response type (
codefor Authorization Code flow) - PKCE verifier/challenge if required
10) Read the provider’s error logs/docs
Many providers have:
- application logs
- OAuth audit logs
- callback/consent error pages
- docs for exact redirect URI requirements
If you want, paste:
- the provider name,
- the callback error/message,
- the redirect URI you configured, and
- the redirect URI you’re sending in the auth request,
and I can help pinpoint the issue quickly.