Shopify OAuth Errors: Codes, Causes & Fixes
Every common error you’ll hit during the Shopify OAuth flow and when calling the Admin API with the resulting token. Each one with the symptom, cause, and exact fix.
By Datora Team · Updated
Where errors happen
The Shopify OAuth 2.0 Authorization Code flow has three places where errors surface, and the fix is different in each:
- Authorization request — you build a URL pointing at
/admin/oauth/authorize; Shopify rejects it before the merchant sees the consent screen. - Authorization callback — the merchant approved (or canceled), and Shopify redirects back to your callback URL with either a
codeor anerror. - Token usage — you have an access token and you’re calling the Admin API. The error is from your API call, not from OAuth itself.
Knowing which phase produced the error narrows the fix dramatically. The reference below is grouped by phase. Need a refresher on the flow itself? Read the step-by-step guide.
Every common error, explained
Access token errors (using the issued token)
OAuth completed and you have a token in hand, but API calls fail.
403 ForbiddenAdmin API call returns 403 with a message about scope or permissions.
+
403 ForbiddenAdmin API call returns 403 with a message about scope or permissions.
Token is valid but doesn't include the scope required for the resource you're calling. For example, calling /products.json with only read_orders.
Re-run the OAuth flow with the missing scope added to your scope list. Existing tokens never auto-expand — the merchant must re-approve.
402 Payment RequiredAdmin API returns 402.
+
402 Payment RequiredAdmin API returns 402.
The merchant's Shopify plan is frozen or overdue. Their store is in a paused/locked state.
There's nothing the app can do. Surface a friendly notice to the merchant pointing them to their Shopify billing.
invalid_token / token revokedAdmin API returns 401, and the merchant has uninstalled or reinstalled your app.
+
invalid_token / token revokedAdmin API returns 401, and the merchant has uninstalled or reinstalled your app.
When a merchant uninstalls, all access tokens for that shop are immediately revoked. Reinstall issues a brand-new token — the old one stays revoked.
Listen for the app/uninstalled webhook to clean up stored tokens. On reinstall, capture the new token from the OAuth callback. Don't try to refresh — Shopify Admin API offline tokens don't have a refresh endpoint. See the rotation guide for the safe re-issue procedure.
423 Locked / shop_lockedAPI returns 423 or an error mentioning shop_locked.
+
423 Locked / shop_lockedAPI returns 423 or an error mentioning shop_locked.
The store is temporarily locked, often during a Shopify-initiated security review or a fraud check.
There's no client-side fix. The merchant has to resolve the lock with Shopify. Pause writes and surface the situation to the merchant.
General troubleshooting
Log the full error response. Shopify usually returns a JSON body with error and error_description fields. Don’t swallow them — log both.
Test against a development store. Spin up a dev store from your Partner Dashboard and exercise the OAuth flow there before going live. Errors against dev stores are easier to reset.
Check the Shopify status page. status.shopify.com shows partial outages that turn into spurious server_error and temporarily_unavailable responses.
Verify your URLs character-by-character. Most OAuth bugs are off-by-one in the redirect URI: a trailing slash, http vs https, or a different port.
Stop reusing authorization codes. The most common cause of invalid_grant is calling the token-exchange endpoint twice with the same code — often because of a retry-on-error helper. Always start a fresh OAuth flow instead of retrying the exchange.
Skip OAuth debugging entirely
If you just need a token for a one-off script or a third-party integration, generate one through the OAuth flow we already run. Paste your Client ID, Client Secret, pick scopes, approve on Shopify, copy your token.
Frequently asked questions
Why am I getting invalid_request from Shopify OAuth?+
invalid_request means a required OAuth parameter is missing or malformed. The most common causes are a missing client_id, an empty scope value, an invalid shop parameter (must be a real *.myshopify.com domain), or a redirect_uri that doesn't match what's registered in your app's settings exactly. Compare your authorization URL parameter-by-parameter against the working example in Shopify's docs.
What does invalid_grant mean in Shopify OAuth?+
invalid_grant means the authorization code returned in your callback can't be exchanged for an access token. Authorization codes are single-use and expire after about 10 minutes. The fix is almost always: don't reuse codes, exchange them server-side immediately, and don't retry the exchange after a failure — start the flow over with a fresh authorization request.
How do I fix HMAC verification failed in Shopify OAuth?+
Build the message to hash from the callback query parameters minus the hmac and signature parameters, sorted alphabetically by key, joined as key=value with & separators. Hash with HMAC-SHA256 using your client secret as the key. Compare to the hmac parameter as a hex string. Common mistakes: leaving hmac in the message, URL-encoding the message before hashing, using the wrong secret, or hashing the body instead of the query.
What does access_denied mean in a Shopify OAuth callback?+
access_denied means the merchant clicked Cancel on the consent screen instead of approving your app. There's no programmatic fix — you have to either reduce the scopes you're requesting (so the merchant trusts the install more) or guide them through the consent screen again with better in-app messaging.
Why does my Shopify access token return 401 Unauthorized?+
Either the token has been revoked (the merchant uninstalled your app), you're sending it on the wrong header (must be X-Shopify-Access-Token, not Authorization: Bearer), or the token belongs to a different shop than the one you're calling. Re-run the OAuth flow against the affected shop to get a fresh token.