alibaba/nacos · warning · IOException

OIDC discovery interrupted

Error message

OIDC discovery interrupted

What it means

Thrown when the thread was interrupted during the blocking HTTP discovery call (httpClient.send). The interrupt flag is re-set before throwing. This is a thread-lifecycle/shutdown condition, not a normal request error.

Source

Thrown at plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/config/OidcProviderMetadataProvider.java:112

            if (response.statusCode() != OidcProtocolConstants.HTTP_STATUS_OK) {
                throw new IOException("Failed to discover OIDC configuration, status: "
                    + response.statusCode());
            }
            Map<String, Object> values = JsonUtils.toObj(response.body(), Map.class);
            if (values == null) {
                throw new IOException("OIDC discovery response is empty");
            }
            OidcProviderMetadata result = new OidcProviderMetadata(
                stringValue(values, OidcProtocolConstants.DISCOVERY_AUTHORIZATION_ENDPOINT),
                stringValue(values, OidcProtocolConstants.DISCOVERY_TOKEN_ENDPOINT),
                stringValue(values, OidcProtocolConstants.DISCOVERY_USERINFO_ENDPOINT),
                stringValue(values, OidcProtocolConstants.DISCOVERY_END_SESSION_ENDPOINT),
                stringValue(values, OidcProtocolConstants.DISCOVERY_JWKS_URI));
            LOGGER.info("OIDC configuration discovered: jwksUri={}", result.getJwksUri());
            return result;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("OIDC discovery interrupted", e);
        } catch (IOException e) {
            throw e;
        } catch (RuntimeException e) {
            throw new IOException("Failed to parse OIDC configuration", e);
        }
    }
    
    private String stringValue(Map<String, Object> values, String key) {
        Object value = values.get(key);
        return value == null ? null : value.toString();
    }
    
    private String trimTrailingSlash(String value) {
        int end = value.length();
        while (end > 0 && value.charAt(end - 1) == '/') {
            end--;
        }
        return value.substring(0, end);

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Treat as transient: retry the operation on a non-interrupted thread (e.g. the next login attempt re-runs discovery).
  2. If it recurs on shutdown, it is benign — the server is stopping.
  3. If it recurs at runtime, check for code incorrectly interrupting the discovery thread.
  4. Ensure the IdP responds within the 5-second discovery timeout to avoid external interrupt-like behavior.
Defensive patterns

Strategy: retry

Try / catch

try {
    metadataProvider.getMetadata();
} catch (IOException e) {
    if ("OIDC discovery interrupted".equals(e.getMessage())) {
        // transient thread interruption — retry once on a fresh path
        if (!Thread.currentThread().isInterrupted()) {
            metadataProvider.getMetadata();
        }
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: The thread performing discovery is interrupted while httpClient.send blocks — typically during application shutdown, a forced thread-pool shutdown, or a timeout-driven interrupt.

Common situations: Server shutting down during the first login request; thread pool interrupted; long discovery latency combined with an aggressive interrupt.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/04d1e11310aa5da4. Report an issue: GitHub.