OAuth PKCE error: invalid_grant — PKCE verification failed / code_verifier does not match code_challenge / code_challenge required
The code_verifier sent to the token endpoint doesn’t match the code_challenge from the authorize request, or PKCE is required but wasn’t sent.
Seen on:
REST API
Meaning
The verifier must be stored between redirect and callback (sessionStorage/cookie) and hashed with SHA-256, base64url-encoded without padding. Losing it across tabs/redirects, using plain vs S256 inconsistently, or encoding mistakes break PKCE.
Common causes
- Verifier lost between authorize and callback (new tab, storage cleared)
- Wrong hashing/encoding (base64 instead of base64url, padding)
- Challenge method mismatch (plain vs S256)
- Public client without PKCE where required
⚡ Quick fix
- Persist the verifier and reuse the exact same string
- Use a library for PKCE generation
- Send code_challenge_method=S256
Detailed fix by platform
JavaScript
- javascript
const verifier = base64url(crypto.getRandomValues(new Uint8Array(32))); const challenge = base64url(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)))); sessionStorage.setItem("pkce_verifier", verifier);
How to diagnose
- Storage — Verifier available at callback?
- Encoding — base64url, no padding
- Method — S256 on both sides
🔧 Still not fixed?
Many errors look alike. If the steps above didn’t solve it, one of these is probably what you’re facing:
Similar errors
- auth/popup-closed-by-user Firebase Auth: auth/popup-closed-by-user / auth/popup-blocked / auth/cancelled-popup-request
- auth/unauthorized-domain Firebase Auth: auth/unauthorized-domain — This domain is not authorized for OAuth operations for your Firebase project
- bad_verification_code GitHub OAuth: {"error":"bad_verification_code","error_description":"The code passed is incorrect or expired."}
Most viewed in Authentication
Other ways to find it
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Was this page helpful?
Report a correction or suggest an improvement
Last updated 7 Oct 2026