Salesforce OAuth and session errors — token endpoint error codes, invalid_grant variants, JWT and client credentials failures, 401 INVALID_SESSION_ID, CLI auth errors
What each Salesforce token or session failure means and how to fix it — the OAuth error codes (invalid_grant and its descriptions, invalid_client_id, invalid_client, invalid_app_access, inactive_user, inactive_org, invalid_scope, invalid_request, redirect_uri_mismatch, rate_limit_exceeded), client credentials sent to the wrong host or without a Run As user, JWT audience and pre-authorization, refresh-token rotation, 401 INVALID_SESSION_ID, and the Salesforce CLI's own auth messages.
markdownreferencev1Y4B5-0VA7stage: operatetrust: officialservice: authinterface: anyinvalid_grantauthentication failureexpired access/refresh tokenuser hasn't approved this consumerIP restricted or invalid login hoursaudience is invalidinvalid_client_idclient identifier is invalidinvalid_clientapp must be installed into orgOAUTH_APPROVAL_ERROR_GENERICinvalid_app_accessinactive_userinactive_orginvalid_scopeinvalid_requestredirect_uri_mismatchredirect_uri_missingrate_limit_exceededserver_error hourly limitaccess_deniedno client credentials user enabledclient credentials My Domaintoken request is already being processedrefresh token rotationINVALID_SESSION_ID401 session expiredAPI_DISABLED_FOR_ORGREQUEST_LIMIT_EXCEEDEDError authenticating with JWTError authenticating with the refresh tokenSF_AUDIENCE_URLOAuth Username-Password Flow Disabled
Salesforce OAuth and session errors
Token endpoint errors arrive as {"error": "<code>", "error_description": "<text>"}. Branch on error, then read error_description. invalid_grant alone covers more than ten causes. Login History in Setup shows the server-side reason for each failed attempt.
invalid_grant
error_description | Cause → fix | Check |
|---|---|---|
authentication failure | The user behind the request can't sign in through this app: deactivated, wrong or locked user, or the OAuth username-password flow is blocked (Login History: "OAuth Username-Password Flow Disabled"). Move to client credentials or JWT | Setup → Login History for the user |
user hasn't approved this consumer | JWT bearer: the user isn't pre-authorized. Set Permitted Users = Admin approved users are pre-authorized and add the user's profile or permission set to the app. Also check that you didn't send a sandbox username to production | The ECA's Policies tab |
audience is invalid | The JWT aud claim doesn't match the authorization server: https://login.salesforce.com, https://test.salesforce.com or the My Domain. The CLI tries several and can be forced with SF_AUDIENCE_URL | The URL you signed into aud |
IP restricted or invalid login hours | Outside the profile's IP ranges or login hours. JWT and SAML bearer flows always enforce IP restrictions; the app's IP Relaxation policy decides the others. Not retryable: alert on it | The profile's Login IP Ranges and Hours |
expired access/refresh token | The refresh token was revoked, expired under the app's refresh token policy, or rotated. Re-authorize | The app's refresh token policy |
| (client credentials) | Salesforce: "For the client credentials flow, the request isn't supported for the host domain." The token request went to login.salesforce.com instead of the My Domain; or the flow isn't enabled; or there's no Run As user (field reports quote "no client credentials user enabled") | The URL you POST to; the ECA's Policies tab |
| (PKCE) | The code_verifier doesn't match the code_challenge (a malformed challenge gives invalid_request instead) | Your client's PKCE code |
Other codes
error | Meaning → fix |
|---|---|
invalid_client_id | Client identifier is invalid: wrong consumer key, or another org's key (after a sandbox refresh, re-read it) |
invalid_client | Wrong or rotated client secret. With "app must be installed into org" (the user sees OAUTH_APPROVAL_ERROR_GENERIC), the app isn't installed and the user lacks the approval permission |
invalid_app_access | An admin hasn't approved this user for the app: add the profile or permission set |
inactive_user / inactive_org | The user was deactivated, or the org is locked, closed or suspended |
invalid_scope | A scope the app doesn't have; for the Agent API, check chatbot_api and sfap_api |
invalid_request | Malformed: not HTTPS, wrong method, bad PKCE parameters, or a JWT/SAML bearer flow without the refresh_token scope |
redirect_uri_mismatch / redirect_uri_missing | The callback isn't exactly the registered one (scheme, host, port, trailing slash), or wasn't sent |
rate_limit_exceeded | Too many login attempts: a client requesting tokens in a loop. Cache tokens and reuse them |
server_error | Authorization requests exceed the hourly limit |
access_denied | The user clicked Deny |
Refresh tokens:
- With rotation on, every refresh returns a new refresh token, and reusing an old one invalidates the current one.
- Concurrent refreshes with the same token fail intermittently (Login History: "Token request is already being processed").
- Serialize refreshes per connection and keep only the latest token.
API calls after a token
| Response | Cause → fix |
|---|---|
401 INVALID_SESSION_ID | The access token expired, was revoked, or was sent to the wrong host. Use the instance_url from the token response; refresh once and retry once. jsforce refreshes automatically when a refresh token or refreshFn is configured |
403 API_DISABLED_FOR_ORG | The edition or the user lacks API access ("API Enabled"), or the user is UI-only |
403 REQUEST_LIMIT_EXCEEDED | The org's API request limit is used up: family 10 shows how to read it |
Salesforce CLI messages
| Message | Meaning |
|---|---|
Error authenticating with JWT config due to: … | The token endpoint rejected the assertion: read the invalid_grant description above |
Error authenticating with the refresh token due to: … | "The stored refresh token is no longer valid (it may have expired, been revoked, or been rotated)": run the login again |
Client ID is required for JWT authentication. | Pass --client-id to sf org login jwt |
Two kinds of text: Salesforce's OAuth errors page gives each code's cause in prose (for example "Client identifier is invalid.", "User hasn’t approved the connected app.", "For the refresh token flow, the refresh or access token is expired."). The error_description values a client actually receives (authentication failure, user hasn't approved this consumer, expired access/refresh token) are quoted from vendor troubleshooting guides and field reports. Match on error and treat descriptions as hints.