LinkedIn confidential OAuth fails when token request includes code_verifier
Prepared for the public UsefulSoftwareCo/executor issue tracker. No credentials, client identifiers, account identifiers, callback codes or private organization details are included.
Problem
LinkedIn's standard confidential authorization-code flow fails in Executor at token exchange with HTTP 401 invalid_client / client authentication failed. The same app credential and a fresh code succeed when the exchange follows LinkedIn's documented confidential web flow.
Live comparisons on 21 September 2026 used fresh authorization codes for the same app, redirect URI and scopes (openid profile email w_member_social). Each exchange posted form-encoded data to https://www.linkedin.com/oauth/v2/accessToken with client_id and client_secret in the request body.
| Authorization request |
Token request |
Result |
| S256 challenge |
Matching code_verifier |
401 invalid_client, client authentication failed |
| Standard confidential flow, no challenge |
No code_verifier |
200, access token issued; /v2/userinfo also returned 200 |
| Standard confidential flow, no challenge |
code_verifier present |
401 invalid_client, client authentication failed |
The controlled third comparison isolates the presence of code_verifier at the token endpoint as sufficient to trigger the observed failure. It does not independently establish how LinkedIn internally selects its authentication mode.
Current implementation
Verified against upstream main commit d27e6737edf010d1b4ce915668e3a42cf5358196:
packages/core/sdk/src/oauth-helpers.ts, buildAuthorizationUrl: always includes code_challenge_method=S256 and code_challenge.
- The same file,
exchangeAuthorizationCode: always includes code_verifier in the token form.
packages/core/sdk/src/oauth-service.ts: always creates and forwards PKCE material for authorization-code sessions.
- The registered-client/start API does not expose a compatible confidential-flow option.
Expected fix
Support LinkedIn's documented confidential web flow for its standard /oauth/v2/authorization endpoint when a confidential client is configured. Omit the PKCE challenge and verifier for that specific flow while preserving client-secret authentication, HTTPS, redirect validation and state validation. Keep PKCE for public clients, native-PKCE endpoints and other providers. Do not implement a generic silent retry without PKCE after authentication failures.
Add regression coverage for the standard LinkedIn confidential request shape and preservation of PKCE for other/public clients. Verify a fresh hosted connection can complete and perform an authenticated identity read.
Provider documentation
Impact
The callback's generic client-authentication error suggests a bad secret and leads to unsuccessful credential replacement. A fresh Executor confidential-client registration reproduces the same failure. The hosted connection remains unbound despite an independently verified working confidential grant.
LinkedIn confidential OAuth fails when token request includes code_verifier
Prepared for the public UsefulSoftwareCo/executor issue tracker. No credentials, client identifiers, account identifiers, callback codes or private organization details are included.
Problem
LinkedIn's standard confidential authorization-code flow fails in Executor at token exchange with HTTP 401
invalid_client/client authentication failed. The same app credential and a fresh code succeed when the exchange follows LinkedIn's documented confidential web flow.Live comparisons on 21 September 2026 used fresh authorization codes for the same app, redirect URI and scopes (
openid profile email w_member_social). Each exchange posted form-encoded data tohttps://www.linkedin.com/oauth/v2/accessTokenwithclient_idandclient_secretin the request body.code_verifierinvalid_client, client authentication failedcode_verifier/v2/userinfoalso returned 200code_verifierpresentinvalid_client, client authentication failedThe controlled third comparison isolates the presence of
code_verifierat the token endpoint as sufficient to trigger the observed failure. It does not independently establish how LinkedIn internally selects its authentication mode.Current implementation
Verified against upstream main commit
d27e6737edf010d1b4ce915668e3a42cf5358196:packages/core/sdk/src/oauth-helpers.ts,buildAuthorizationUrl: always includescode_challenge_method=S256andcode_challenge.exchangeAuthorizationCode: always includescode_verifierin the token form.packages/core/sdk/src/oauth-service.ts: always creates and forwards PKCE material for authorization-code sessions.Expected fix
Support LinkedIn's documented confidential web flow for its standard
/oauth/v2/authorizationendpoint when a confidential client is configured. Omit the PKCE challenge and verifier for that specific flow while preserving client-secret authentication, HTTPS, redirect validation and state validation. Keep PKCE for public clients, native-PKCE endpoints and other providers. Do not implement a generic silent retry without PKCE after authentication failures.Add regression coverage for the standard LinkedIn confidential request shape and preservation of PKCE for other/public clients. Verify a fresh hosted connection can complete and perform an authenticated identity read.
Provider documentation
client_id,client_secret,code,grant_typeandredirect_uriin the token form.Impact
The callback's generic client-authentication error suggests a bad secret and leads to unsuccessful credential replacement. A fresh Executor confidential-client registration reproduces the same failure. The hosted connection remains unbound despite an independently verified working confidential grant.