apache/pulsar · error · IllegalStateException
Interrupted initializing OAuth2 IdP TLS factory
Error message
Interrupted initializing OAuth2 IdP TLS factory
What it means
During OAuth2 client setup, StandaloneOAuth2HttpClientFactory asynchronously initializes a TLS factory for the identity-provider connection. If the thread waiting on `factory.initialize(...).get()` is interrupted, the factory is closed, the interrupt flag is restored, and this IllegalStateException is thrown. It means initialization was cancelled, typically by application or client shutdown.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/StandaloneOAuth2HttpClientFactory.java:113
if (executor != null) {
executor.shutdownNow();
}
throw e;
}
}
private static PulsarTlsFactory buildIdpTlsFactory(TlsPolicy policy, int refreshIntervalSeconds,
ScheduledExecutorService executor) {
FileBasedTlsFactory factory = new FileBasedTlsFactory(
Map.of(TlsPurpose.CLIENT_OAUTH2, policy),
FileBasedTlsFactorySettings.builder().refreshIntervalSeconds(refreshIntervalSeconds).build(),
Map.of());
try {
factory.initialize(initContext(executor)).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
closeQuietly(factory);
throw new IllegalStateException("Interrupted initializing OAuth2 IdP TLS factory", e);
} catch (ExecutionException e) {
closeQuietly(factory);
Throwable cause = e.getCause() != null ? e.getCause() : e;
throw new IllegalStateException("Failed to initialize OAuth2 IdP TLS factory: " + cause.getMessage(),
cause);
}
return factory;
}
private static TlsFactoryInitContext initContext(ScheduledExecutorService executor) {
return new TlsFactoryInitContext() {
@Override
public Map<String, String> params() {
return Map.of();
}
@Override
public ScheduledExecutorService scheduler() {View on GitHub (pinned to 820761864e)
Solutions
- Retry client creation from a non-interrupted thread after shutdown activity settles.
- Fix lifecycle ordering: never construct the OAuth2 client concurrently with closing the Pulsar client or its executors.
- Find the interrupt source (Future.cancel(true), shutdownNow) and sequence OAuth2 init before shutdown.
- Preserve the interrupt status in caller code; do not swallow InterruptedException upstream.
Defensive patterns
Strategy: retry
Validate before calling
if (Thread.currentThread().isInterrupted()) {
throw new IllegalStateException("Cannot init OAuth2 client on an interrupted thread");
} Try / catch
try {
client = AuthenticationFactoryOAuth2.clientCredentials(issuerUrl, credFile, audience);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Interrupted initializing")) {
// thread was interrupted during TLS factory init;
// propagate shutdown or retry on a fresh thread after checks
throw e;
}
throw e;
} Prevention
- Construct the OAuth2/Pulsar client before shutdown hooks run; don't init inside shutdown paths.
- Avoid Future.cancel(true) and executor.shutdownNow() on threads performing client init.
- Sequence client lifecycle: create -> use -> close, ensuring init never races close.
When it happens
Trigger: AuthenticationFactoryOAuth2.clientCredentials/refreshToken invoked from a thread interrupted while blocked on the TLS-factory initialization future — e.g. during Pulsar client close, executor shutdownNow, or Future.cancel(true) racing client construction.
Common situations: Container/pod shutdown racing client creation; framework timeouts interrupting worker threads; reusing a shutting-down ScheduledExecutorService; lifecycle misordering where init races close.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Failed to initialize OAuth2 IdP TLS factory: ${cause.getMess
- certFilePath must not be null
- keyFilePath must not be null
- certStream provider or stream must not be null
- keyStream provider or stream must not be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/6b2731199ded884d.
Report an issue: GitHub.