Salesforce sends an authorization error to your callback URL as query parameters, for example ?error=access_denied, and a token error as JSON from the token endpoint, such as {"error":"invalid_grant","error_description":"expired access/refresh token"} (OAuth 2.0 Authorization Errors, Salesforce, read 16 Oct 2026). The pair of values is the diagnosis. Every section below is named after one of them.
A different login error? Match it to its fix in Can't log in to Salesforce?
Salesforce OAuth error codes and what they mean
| error | Salesforce's stated cause | First fix |
|---|---|---|
invalid_grant | Bad code or credentials, invalid user, assertion or audience, IP or login hours, PKCE verifier mismatch, app not approved, expired refresh token, authentication failure | Read error_description; most cases mean the user re-authorizes |
redirect_uri_mismatch | Redirect URI does not match the app definition | Make the callback URL identical in the app and the request |
redirect_uri_missing | No redirect URI sent | Add redirect_uri to the authorize request |
invalid_request | HTTPS, GET or POST required; invalid or unexpected code_challenge; JWT and SAML bearer flows need the refresh_token scope | Fix the request shape the description names |
invalid_client / invalid_client_id | Client secret, or client identifier, is invalid | Recopy the consumer key and secret; check you call the right org |
invalid_app_access | User is not approved by an admin to use the app | Grant access through the user's profile or a permission set |
inactive_user / inactive_org | User deactivated; org locked, closed or suspended | Reactivate the user; for an inactive org, contact Salesforce |
rate_limit_exceeded | Too many login attempts | Stop the retry loop and find which host is calling |
invalid_grant: expired access/refresh token
The refresh token is no longer valid. It may have expired under the app's refresh token policy, been revoked, or been rotated: with Refresh Token Rotation, every refresh issues a new refresh token and retires the old one, and reusing a retired token revokes the current refresh token and its access tokens too. Salesforce's guidance is to catch the error, log it, and start a fresh authorization instead of retrying the same token, and to save the new refresh token from every refresh response (Enforce One-Time-Use Refresh Tokens with Refresh Token Rotation, Salesforce, published 9 Oct 2026).
We hit a version of this in our own backend. In May 2026, three tool calls in our ApexGenius service caught a 401 within 0.4 seconds and each refreshed the same token; the earlier access tokens stopped working mid-call. The fix was one refresh at a time per user: a lock around the refresh, and a check inside it that returns the token another caller just fetched. We now treat invalid_grant as “ask the user to reconnect”.
invalid_grant: authentication failure
For a JWT bearer connection that fails some of the time, Salesforce traced the cause to Login Rate Exceeded for the integration user: another host was sending login requests in volume and the user was blocked (OAuth JWT connection fails with invalid_grant authentication failure, Salesforce, published 2 Mar 2024). Find that host in the logs and stop it. For the Salesforce CLI, the same text points at org access: the org and the user both need API access, and the instance URL must be the org's My Domain URL in the enhanced format, not a Lightning URL (Resolve Common Authorization Errors (Salesforce DX Developer Guide), Salesforce, read 16 Oct 2026).
invalid_grant: user hasn't approved this consumer
The user the JWT names is not allowed to use the app. Set Permitted Users to “Admin approved users are pre-authorized” and add the user's profile or permission set to the app. If the app is new, wait a few minutes for it to finish replicating before you try again (Resolve Common Authorization Errors (Salesforce DX Developer Guide), Salesforce, read 16 Oct 2026). Salesforce's connector article fixes the same error through the profile's Connected App Access setting (OAuth JWT connection "user hasn't approved this consumer", Salesforce, published 2 Mar 2024).
redirect_uri_mismatch: redirect_uri must match configuration
The full error reads error=redirect_uri_mismatch&error_description=redirect_uri%20must%20match%20configuration. The redirect URI in the authorize request is not one of the callback URLs saved on the app (OAuth 2.0 Authorize Fails With Error "redirect_uri_mismatch", Salesforce, published 2 Mar 2024).
- Copy the exact
redirect_urifrom the failing request, including scheme, host, port and path. - In the app's OAuth settings, add that exact value as a callback URL, or change the client to send one already listed.
- If your org moved to enhanced domains, check both the old and new My Domain host names.
- Retry a few minutes after saving; a new or changed app can take that long to replicate.
For the Salesforce CLI with your own connected app, the callback is http://localhost:1717/OauthRedirect unless you changed the port (Create a Connected App in Your Org (Salesforce DX Developer Guide), Salesforce, read 16 Oct 2026).
For businesses on Salesforce
No second Salesforce admin? Set one up before the next lockout.
error=invalid_request&error_description=missing required code challenge
PKCE (Proof Key for Code Exchange) is required and the authorize request did not include a code_challenge. Salesforce can require it per app, with “Require Proof Key for Code Exchange (PKCE) Extension for Supported Authorization Flows”, or for the whole org, with “Require Proof Key for Code Exchange (PKCE)” under Setup, OAuth and OpenID Connect Settings. When either is on, the web server flow and the other authorization code flows without PKCE are blocked (Enabling PKCE for OAuth for External Client and Connected Apps, Salesforce, published 22 Sep 2026).
- Generate a random
code_verifierin the client and derive thecode_challengefrom it with SHA-256. - Send
code_challengeandcode_challenge_method=S256on the authorize request. - Send the original
code_verifieron the token request. - Turn on the org-wide requirement only after every client sends PKCE; Salesforce warns that switching it on can cause downtime for integrations that do not.
Two related strings: invalid_grant when the code_verifier does not match the challenge, and invalid_request when the flow did not expect a code_challenge at all (OAuth 2.0 Authorization Errors, Salesforce, read 16 Oct 2026). If the request that fails is one Salesforce generates itself, your configuration cannot fix it. That happened to us during 2GP namespace linking, and the full account, with the support case Salesforce confirmed as a bug, is in Codex found a Salesforce 2GP bug and filed the ticket.
“Contact Salesforce Customer Support to enable the creation of connected apps in your org”
From Spring '26, creating connected apps is disabled by default because Salesforce is deprecating them. Existing connected apps keep working. The replacement is an external client app, which Salesforce calls the preferred integration framework (Create a Connected App in Your Org (Salesforce DX Developer Guide), Salesforce, read 16 Oct 2026), and Trailhead's external client app module covers how it splits developer and admin settings (Trailhead, Salesforce, read 16 Oct 2026).
If you need a connected app, for example a Salesforce CLI Dev Hub that will create scratch orgs or sandboxes, Salesforce Customer Support enables an org permission once per org. After that, in Setup, open External Client Apps, then Settings, turn on Allow creation of connected apps and click Enable.
invalid_client and invalid_client_id
The client secret or the client identifier is wrong for this org (OAuth 2.0 Authorization Errors, Salesforce, read 16 Oct 2026). Recopy the consumer key and secret, and check the request goes to the org that owns the app. In our backend this raises a configuration alert for an operator, while invalid_grant asks the user to reconnect, and a saved refresh token is never sent to a client ID that differs from the one that issued it.
Integration user cannot log in after MFA enforcement
API logins do not need MFA, but the OAuth web server, user-agent and username-password flows, and SOAP login(), go through a UI login that does. Login History shows them in the Login Subtype field. Salesforce's fix is to move the integration to the JWT bearer flow or the client credentials flow (Resolve Passkey Login Issues in Salesforce, Salesforce, published 12 Oct 2026), which Salesforce lists as unaffected by the passkey requirement. Our own deploy pipeline uses client credentials; the setup is in Salesforce CI/CD with GitHub Actions. In June 2026 we also narrowed the scope our connector requests from full to api, which covers every API it calls and still runs only with the signed-in user's permissions.
If nobody on your team owns your Salesforce integrations
We are an independent Salesforce consultancy, separate from Salesforce Support. We cannot unlock a user, reset MFA or change an admin's email from outside your org; only an admin inside it, or Salesforce, can. What we do is the work that keeps a business from depending on one login: a second admin, a break-glass account, passkeys enrolled for everyone who needs them, and SSO and integrations that keep working through the next change. That is the admin work inside our Salesforce managed services.
Frequently asked questions
What does invalid_grant mean in Salesforce?
Salesforce rejected the grant itself. Its error table lists an invalid authorization code, bad user credentials, an invalid user, assertion or audience, an IP restriction or login hours, a PKCE verifier that does not match, a user who has not approved the app, an expired refresh token, and an authentication failure. The error_description says which one.
How do I fix redirect_uri_mismatch in Salesforce?
Make the redirect_uri your app sends identical to a callback URL saved on the connected app or external client app: same scheme, host, port and path. Salesforce returns redirect_uri must match configuration when they differ.
What does missing required code challenge mean?
The app, or the whole org, requires PKCE, and the authorization request arrived without a code_challenge. Send code_challenge and code_challenge_method on the authorize request and the matching code_verifier on the token request.
Why does Salesforce say to contact customer support to enable connected apps?
Creating new connected apps is disabled by default from Spring '26, because Salesforce is deprecating them. Existing connected apps keep working. Create an external client app instead; if you need a connected app, Salesforce Customer Support enables an org permission once per org.
Which Salesforce OAuth flow should an integration use after MFA enforcement?
A flow with no UI login. Salesforce lists the JWT bearer flow and the client credentials flow as unaffected by MFA enforcement, and recommends them for integration users whose web server, user-agent or username-password logins started failing.
Where do I find a Salesforce consumer key?
On a connected app, click Manage Consumer Details, verify your identity with the emailed code if asked, and copy the Consumer Key (and Consumer Secret if your flow uses it). On an external client app, the key and secret sit in its OAuth settings, kept apart from the less sensitive settings.