Introduction
APIs that use opaque bearer tokens (non-JWT) must validate each token by calling the OAuth2 server's introspection endpoint (RFC 7662). When the OAuth2 server is unreachable -- due to network issues, server downtime, or DNS failures -- the API cannot validate any tokens and must either reject all requests or implement a fallback strategy.
Symptoms
- All API requests return
401 Unauthorizedregardless of token validity - API logs show
introspection endpoint unreachableorconnection timeout - OAuth2 server health check fails
- Requests work with JWT tokens (which can be validated locally) but fail with opaque tokens
- Error message:
Failed to introspect token: connection timed out to https://auth.example.com/oauth/introspect
Common Causes
- OAuth2 server crashed or was taken offline for maintenance
- Network connectivity issue between the API and the OAuth2 server
- DNS resolution failure for the OAuth2 server hostname
- OAuth2 server firewall rules blocking access from API servers
- OAuth2 server overloaded and not responding within the API's timeout
Step-by-Step Fix
- 1.Verify the OAuth2 server is reachable: Test connectivity.
- 2.```bash
- 3.# Check DNS resolution
- 4.dig auth.example.com +short
- 5.# Test HTTPS connectivity
- 6.curl -v https://auth.example.com/oauth/introspect
- 7.# Check OAuth2 server health endpoint
- 8.curl -s https://auth.example.com/.well-known/openid-configuration
- 9.
` - 10.Restart or recover the OAuth2 server: Restore the introspection endpoint.
- 11.```bash
- 12.# Check OAuth2 server status
- 13.systemctl status keycloak # or your OAuth2 server
- 14.# Restart if needed
- 15.systemctl restart keycloak
- 16.# Verify the introspection endpoint works
- 17.curl -X POST https://auth.example.com/oauth/introspect \
- 18.-d "token=test-token" \
- 19.-u "client:secret"
- 20.
` - 21.Implement token caching to tolerate OAuth2 outages: Cache introspection results.
- 22.```java
- 23.// Cache introspection results for the token's remaining lifetime
- 24.@Cacheable(value = "tokenIntrospection", key = "#token")
- 25.public TokenIntrospection introspect(String token) {
- 26.return oauth2Client.introspect(token);
- 27.}
- 28.// Set cache TTL based on the token's 'exp' claim from the introspection response
- 29.
` - 30.Implement a circuit breaker for the introspection call: Fail fast during outages.
- 31.```java
- 32.@CircuitBreaker(name = "oauth2", fallbackMethod = "introspectFallback")
- 33.public TokenIntrospection introspect(String token) {
- 34.return oauth2Client.introspect(token);
- 35.}
public TokenIntrospection introspectFallback(String token, Exception e) { // Return cached result or reject with clear error return TokenIntrospection.unavailable("OAuth2 server temporarily unavailable"); } ```
- 1.Verify API authentication works after recovery: Test with a valid token.
- 2.```bash
- 3.curl -H "Authorization: Bearer $VALID_TOKEN" https://api.example.com/resource
- 4.# Should return 200 OK
- 5.
`
Prevention
- Deploy OAuth2 servers in a highly available configuration (multi-node cluster)
- Implement introspection result caching with TTL based on token expiration
- Use JWT tokens instead of opaque tokens to enable local validation
- Configure circuit breakers with fallback strategies for OAuth2 unavailability
- Monitor OAuth2 server health and introspection endpoint latency
- Implement API-level token caching to reduce introspection call frequency