The validating server's clock is behind the issuing server's clock. JWT has nbf (not before) timestamp set by issuer. If validator's time is earlier than nbf, validation fails even if token is valid. Even +1 second clock skew causes failures. Example: Auth server time 10:00:00 issues JWT with nbf: 10:00:00, API server time 09:59:59 rejects it. Solution: Set clockTolerance in JWT verification or sync clocks with NTP.
JWT Clock Skew FAQ & Answers
5 expert JWT Clock Skew answers researched from official documentation. Every answer cites authoritative sources you can verify.
unknown
5 questions60 seconds (1 minute) is recommended for most systems. Pattern: jwt.verify(token, secret, { clockTolerance: 60 }). This accounts for normal clock drift between servers. Industry defaults: Most JWT libraries use 300 seconds (5 minutes) default, but 60 seconds is safer. Use 300 seconds only for mobile clients with unreliable clocks. Use 30 seconds for high-security with NTP sync. Use 120 seconds for cross-region deployments. Clock tolerance applies to both nbf and exp claims.
Install NTP daemon: sudo apt-get install ntp, enable: sudo systemctl enable ntp, start: sudo systemctl start ntp. Verify sync: timedatectl status shows 'System clock synchronized: yes'. Check time sources: ntpq -p shows NTP servers and offset. Force immediate sync: sudo service ntp stop; sudo ntpdate pool.ntp.org; sudo service ntp start. Configure NTP servers in /etc/ntp.conf using pool.ntp.org. Monitor drift with ntpq -p regularly. Drift should be <100ms for production servers. AWS/GCP provide NTP endpoints: time.google.com or 169.254.169.123.
Fetch time from trusted source periodically, compare to local time. Pattern: const response = await fetch('https://worldtimeapi.org/api/ip'); const { unixtime } = await response.json(); const localTime = Math.floor(Date.now() / 1000); const skew = Math.abs(localTime - unixtime); if (skew > 60) alert('Clock skew detected', { skew }). Run every hour: setInterval(checkClockSkew, 3600000). Alert if skew >60 seconds. Log skew value for trending. Alternative endpoints: time.google.com (requires HTTP client that follows redirects). Export metric to Prometheus for alerting.
No, use clock tolerance instead of rejecting requests. Hard requirement for synchronized clocks breaks system when NTP fails. RFC 8725 and OWASP 2025 guidance: Set minimal clockTolerance (30 seconds recommended by Curity, 300 seconds Microsoft default) and monitor drift. Curity 2025 best practice: 'A few seconds should usually be enough; we don't recommend using more than 30 seconds.' Alert operations when drift >30s but keep serving. Pattern: jwt.verify(token, secret, { clockTolerance: 30 }). Only reject if drift >5 minutes (catastrophic NTP failure). Monitor closely: OWASP 2025 report shows misconfigured token validation contributed to 40% of API authentication breaches. Graceful degradation prevents cascading failures. Use timedatectl status to verify NTP sync, configure NTP (pool.ntp.org) for <100ms drift. Balance security (minimal tolerance) with reliability (some tolerance required for distributed systems per RFC 8725).