Come appare il messaggio
{"error":"invalid_grant","error_description":"Code not valid"}Cause frequenti
- Authorization code scaduto (spesso dopo 30–60 secondi) o già usato, ad es. per doppio clic o reload del browser.
- La redirect_uri della richiesta token è diversa da quella della richiesta authorize.
- Refresh token scaduto, revocato o sessione IdP chiusa (Keycloak: “Session not active”).
- PKCE: il code_verifier non corrisponde al code_challenge.
- Gli orologi di client e IdP sono molto sfasati.
Verifica
- Controlla la sincronizzazione dell'ora
timedatectl | grep -E 'synchronized|Local time' - Cerca l'errore nei log del client o dell'IdP
journalctl --since '15 min ago' | grep -iE 'invalid_grant|token endpoint|oidc' - Mostra issuer e token endpoint dell'IdP
curl -s https://sso.example.com/realms/main/.well-known/openid-configuration | jq -r '.issuer, .token_endpoint'
Soluzione
- Rifai il login da capo, senza tasto indietro né reload sull'URL di callback.
- Tieni la redirect_uri identica in app e IdP, protocollo e slash finale compresi.
- Sincronizza l'ora via NTP:
timedatectl set-ntp true. - Per errori di refresh allinea la durata delle sessioni sull'IdP con quella dei token dell'app.
- Più istanze dietro un load balancer: usa uno storage di sessione condiviso, così il verifier PKCE è disponibile ovunque.
Domande frequenti
Cosa significa “Code not valid” in Keycloak?
Il codice è già stato usato, è scaduto o appartiene a un'altra sessione. Spesso la causa è una seconda chiamata al callback per reload o prefetch.
L'utente deve fare qualcosa?
Di solito basta un nuovo login. Se succede spesso, il problema è nella configurazione di app, proxy o IdP.