Error

OAuth PKCE Error โ€” Fix

Updated April 2026

Reading this article? Verify your fix in real-time. Debug this PKCE error โ€” OAuthFixer โ†’
OAuth Error Response
{"error": "invalid_grant", "error_description": "PKCE verification failed: code_verifier does not match code_challenge"}

The code_verifier you sent in the token exchange does not match the code_challenge you sent in the authorization request. They must be cryptographically linked โ€” the challenge is the SHA-256 hash of the verifier.

Common causes

Correct PKCE implementation

// Generate verifier and store BEFORE redirecting
const verifier = generateVerifier();
sessionStorage.setItem('pkce_verifier', verifier); // store here

const challenge = await sha256Base64url(verifier);
// redirect to auth with code_challenge=challenge

// On callback โ€” retrieve the STORED verifier
const verifier = sessionStorage.getItem('pkce_verifier'); // NOT regenerated
await exchangeCode(code, verifier);
function generateVerifier() { const array = new Uint8Array(32); crypto.getRandomValues(array); return btoa(String.fromCharCode(...array)) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}

async function sha256Base64url(str) { const data = new TextEncoder().encode(str); const digest = await crypto.subtle.digest('SHA-256', data); return btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
Debug your OAuth PKCE error โ†’ OAuthFixer