{"record":{"id":"6b2731199ded884d","repo":"apache/pulsar","slug":"interrupted-initializing-oauth2-idp-tls-factory","errorCode":null,"errorMessage":"Interrupted initializing OAuth2 IdP TLS factory","messagePattern":"Interrupted initializing OAuth2 IdP TLS factory","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/StandaloneOAuth2HttpClientFactory.java","lineNumber":113,"sourceCode":"            if (executor != null) {\n                executor.shutdownNow();\n            }\n            throw e;\n        }\n    }\n\n    private static PulsarTlsFactory buildIdpTlsFactory(TlsPolicy policy, int refreshIntervalSeconds,\n            ScheduledExecutorService executor) {\n        FileBasedTlsFactory factory = new FileBasedTlsFactory(\n                Map.of(TlsPurpose.CLIENT_OAUTH2, policy),\n                FileBasedTlsFactorySettings.builder().refreshIntervalSeconds(refreshIntervalSeconds).build(),\n                Map.of());\n        try {\n            factory.initialize(initContext(executor)).get();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            closeQuietly(factory);\n            throw new IllegalStateException(\"Interrupted initializing OAuth2 IdP TLS factory\", e);\n        } catch (ExecutionException e) {\n            closeQuietly(factory);\n            Throwable cause = e.getCause() != null ? e.getCause() : e;\n            throw new IllegalStateException(\"Failed to initialize OAuth2 IdP TLS factory: \" + cause.getMessage(),\n                    cause);\n        }\n        return factory;\n    }\n\n    private static TlsFactoryInitContext initContext(ScheduledExecutorService executor) {\n        return new TlsFactoryInitContext() {\n            @Override\n            public Map<String, String> params() {\n                return Map.of();\n            }\n\n            @Override\n            public ScheduledExecutorService scheduler() {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/oauth2/StandaloneOAuth2HttpClientFactory.java#L95-L131","documentation":"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.","triggerScenarios":"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.","commonSituations":"Container/pod shutdown racing client creation; framework timeouts interrupting worker threads; reusing a shutting-down ScheduledExecutorService; lifecycle misordering where init races close.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if (Thread.currentThread().isInterrupted()) {\n    throw new IllegalStateException(\"Cannot init OAuth2 client on an interrupted thread\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    client = AuthenticationFactoryOAuth2.clientCredentials(issuerUrl, credFile, audience);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Interrupted initializing\")) {\n        // thread was interrupted during TLS factory init;\n        // propagate shutdown or retry on a fresh thread after checks\n        throw e;\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["oauth2","tls","interruption","shutdown","pulsar-client"],"backgroundTag":"thread-interrupted","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}