Debugging Sign In with LinkedIn (OpenID Connect): Symptoms, Causes, and Fixes
A diagnostic guide to Sign In with LinkedIn via OpenID Connect: map each error (unauthorized_scope_error, invalid_redirect_uri, token 401) to its cause and fix.
18 Aug 2025, 14:04 UTC

If your LinkedIn login flow suddenly returns unauthorized_scope_error, invalid_redirect_uri, or a 401 at the token exchange, the problem is almost always one of a handful of configuration mismatches — and each error maps to a specific fix. This guide walks through the failure symptoms of the supported 'Sign In with LinkedIn using OpenID Connect' flow, the checks to run in order, and when to stop debugging locally and escalate.
Version assumption: this reflects LinkedIn's OIDC-based sign-in product, which replaced the legacy OAuth 2.0 member-auth flow with r_* scopes. Scope names, endpoints, and approval requirements change over time, so confirm details against current LinkedIn documentation before shipping.
Recognizing the failure
The flow has four stages: build the authorize URL, capture the authorization code, exchange the code for tokens, and call /userinfo. Your first diagnostic step is identifying which stage fails:
- Redirect fails immediately with an error page or an error parameter on your callback (
unauthorized_scope_error,invalid_redirect_uri). - Code is returned but token exchange fails with HTTP 400/401/403 from the token endpoint.
- Token succeeds but profile data is missing or the userinfo call returns an error.
Record the exact error code and stage before changing anything — the fix depends on it.
Symptom-to-cause map
| Symptom | Most likely cause | Fix section |
|---|---|---|
unauthorized_scope_error at authorize | Legacy scopes requested, or OIDC product not added to the app | Fix 1 and 2 |
invalid_redirect_uri | Redirect URI doesn't exactly match a registered URL | Fix 3 |
| 401/403 at token exchange | Wrong credential placement, or expired/reused authorization code | Fix 4 |
| Userinfo returns minimal or no profile fields | profile or email scope not granted | Fix 5 |
Ordered checks
- Confirm the product is enabled. In the LinkedIn developer portal, open your app and check that 'Sign In with LinkedIn using OpenID Connect' is listed under Products. Without it, scope requests are rejected even with valid client credentials.
- Check the scopes in your authorize URL. The OIDC flow uses
openid,profile, andemail. If you migrated from the legacy flow, remover_liteprofileandr_emailaddress— requesting them causesunauthorized_scope_erroron apps where they're unavailable (which includes most newly created apps). - Compare the redirect URI character-for-character. The
redirect_uriin the authorize request must exactly match a registered URL in the portal: scheme, host, path, port, and trailing slash.https://app.example.com/auth/linkedin/callbackand.../callback/are different values. Watch for framework helpers that silently append slashes or change casing. - Verify the token exchange request. LinkedIn expects
client_idandclient_secretsent consistently — either both in the POST body or via HTTP Basic auth, matching what your HTTP client library actually emits. Also confirm the code is fresh: authorization codes are single-use and short-lived, so a retried or delayed exchange will fail. - Decode what was actually granted. Check the scope value in the token response (or the consent screen shown to the user) and confirm it includes
openid profile email. A user can decline optional scopes, which produces a successful login with missing data.
Fixes tied to findings
Fix 1: Correct the scope set
Build the authorize URL with the OIDC scopes only:
https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REGISTERED_CALLBACK&scope=openid%20profile%20emailRun this in any browser or HTTP client; no special permissions needed. Replace the placeholders with your app's values. Expected result: a LinkedIn consent screen, not an error page.
Fix 2: Add the OIDC product
In the developer portal, add 'Sign In with LinkedIn using OpenID Connect' to the app and wait for it to show as active. Retry the authorize URL afterward.
Fix 3: Align the redirect URI
Copy the exact callback URL your code sends (log the outgoing authorize URL, not the token) and paste it verbatim into the app's registered redirect URLs. Redeploy or restart if your framework caches OAuth config.
Fix 4: Repair the token exchange
A minimal exchange, run from your server or locally with curl:
curl -X POST https://www.linkedin.com/oauth/v2/accessToken -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=authorization_code' -d 'code=CODE_FROM_CALLBACK' -d 'redirect_uri=YOUR_REGISTERED_CALLBACK' -d 'client_id=YOUR_CLIENT_ID' -d 'client_secret=YOUR_CLIENT_SECRET'Use a freshly captured code — codes expire quickly and cannot be replayed. Do not log codes or tokens; they are bearer credentials. Expected result: a JSON body with access_token and an id_token.
Fix 5: Fetch profile from userinfo
Profile data comes from the OIDC userinfo endpoint, not the legacy /v2/me or email endpoints:
curl https://api.linkedin.com/v2/userinfo -H 'Authorization: Bearer ACCESS_TOKEN'Expected result: a JSON object with sub, name, and (if the email scope was granted) email. Missing fields mean the corresponding scope wasn't granted — re-check the consent screen and granted scopes rather than the endpoint.
Limitations and verification
Behavior differs between older developer apps (which may still have legacy scopes) and new ones, so don't assume a fix that works on one app transfers to another. To verify a fix end-to-end, replay the full four-stage flow with a minimal HTTP client and record the exact response at each step. Test with a second LinkedIn account to rule out member-level consent issues.
When to escalate
Contact LinkedIn developer support when: the app review or verification status blocks the scopes you need; errors persist after you've verified the product, scopes, redirect URI, and token exchange against the portal configuration; or you hit rate limits or approval requirements that changed behavior. Include the exact error code, the failing stage, and your app ID — never tokens or codes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.