Mensagem de erro
"nbf" claim timestamp check failed
jose (JavaScript) — JWTClaimValidationFailed, code ERR_JWT_CLAIM_VALIDATION_FAILED
O que significa
O token traz uma claim `nbf` (“not before”) que, pelo relógio do verificador, ainda está no futuro; por isso o jose o rejeita como ainda não válido. A assinatura e as demais claims podem estar perfeitamente corretas; o erro diz respeito apenas ao tempo. Quase sempre significa que os relógios do emissor e do verificador divergem mais do que a tolerância que você permite (zero por padrão).
Por que acontece
O relógio do verificador está atrasado em relação ao do emissor
comumMuitos emissores definem `nbf` igual ao horário de emissão. Se o relógio do host que faz a verificação estiver atrasado, mesmo que só alguns segundos, todo token recém-emitido vem “do futuro” durante esse intervalo. Contêineres e VMs herdam o relógio do host, então um único host com o relógio desajustado quebra de uma vez todos os serviços que rodam nele.
Token usado no instante em que foi emitido, sem tolerância
comumTestes e chamadas entre serviços muitas vezes geram um token e o enviam em milissegundos. Com `clockTolerance` no valor padrão de 0 segundos, a diferença normal entre os relógios de duas máquinas basta para causar falhas intermitentes.
O emissor definiu nbf no futuro de propósito
ocasionalAlguns sistemas emitem antecipadamente tokens que só passam a valer mais tarde (jobs agendados, links de ativação adiada). Usar um token assim antes da hora é uma rejeição correta — quem chama precisa esperar até o `nbf`.
nbf gravado em milissegundos
raraOs horários do JWT são segundos desde a época Unix (RFC 7519, NumericDate). Um emissor que grava `Date.now()` gera um `nbf` cerca de 50.000 anos no futuro, e o token nunca se torna válido.
Como corrigir
- 1.
Permitir uma diferença de relógio pequena e explícita
A opção `clockTolerance` aceita segundos ou uma string de duração. Uma tolerância de 30 a 60 segundos absorve o desvio que ocorre na prática; ela não serve para aceitar tokens minutos antes da hora.
js import { jwtVerify } from "jose"; const { payload } = await jwtVerify(token, jwks, { algorithms: ["ES256"], clockTolerance: "30s", // applies to nbf, exp and iat }); - 2.
Imprimir a linha do tempo antes de mudar a configuração
Compare o `nbf` com a hora atual do verificador. Uma diferença de segundos indica relógios dessincronizados; de horas, um bug de fuso horário ou de unidade no emissor; um `nbf` de 13 dígitos, milissegundos.
js import { decodeJwt } from "jose"; const { iat, nbf, exp } = decodeJwt(token); const now = Math.floor(Date.now() / 1000); console.log({ iat, nbf, exp, now, nbfInSeconds: nbf - now }); - 3.
Corrigir o relógio que se desajusta
Rode o NTP (chrony ou systemd-timesyncd) em todo host que emite ou verifica tokens. A tolerância esconde pequenas diferenças de relógio; ela não deveria precisar esconder diferenças grandes.
bash timedatectl status # "System clock synchronized: yes" chronyc tracking # offset from the NTP reference date -u +%s # compare with the token's nbf