PKCE verification failed 🔐 Authentication

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

  1. Persist the verifier and reuse the exact same string
  2. Use a library for PKCE generation
  3. Send code_challenge_method=S256

Detailed fix by platform

JavaScript

  1. 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

  1. Storage — Verifier available at callback?
  2. Encoding — base64url, no padding
  3. 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:

🧠 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.