Hi all,
I have a Jira account request waiting for review in the self-serve queue and
was hoping a PMC member could take a look when there is a moment.
Requested username: kevinyoo
Real name: Seokmo Yoo
Submitted: September 1, 2026
Project selected: Kafka
I am asking here because the self-serve queue is the only route since public
signup was disabled, and I do not want the request to sit unnoticed.
The account is for two SASL/OAUTHBEARER issues I ran into while running Kafka
clients inside a container that gives each deployment its own class loader.
Both have a fix and tests ready, rebased on current trunk.
1. LoginManager is shared across class loaders
LoginManager is cached by JAAS configuration, login class, login callback
class and the sasl.* configs, but not by the class loader of the caller.
When two deployments in one JVM use the same JAAS configuration they share
a LoginManager, so its reference count never reaches zero and the
OAUTHBEARER refresh thread outlives the deployment that created it. That
thread keeps the discarded class loader as its context class loader, and
because LoginContext resolves login modules through ServiceLoader, every
later re-login fails the same way:
LoginException: IllegalStateException: Trying to access closed classloader
Once the token expires, any client that has to re-authenticate is rejected.
The fix adds the context class loader to the cache key. It is three lines
in LoginManager, plus a regression test. Single-class-loader deployments,
including brokers, are unaffected because the key is then identical for
every caller.
I could not find an existing ticket for this, so this is the one I need an
account to file.
2. KAFKA-14102
This one is already filed and still open. It reproduces on current trunk.
Sasl.createSaslClient resolves the factory through the JVM-wide security
provider registry, and Security.addProvider keeps only the first provider
registered under a given name, so the OAUTHBEARER factory belongs to
whichever class loader initialized OAuthBearerLoginModule first and cannot
use a callback handler from any other one.
The fix has two parts: the factory returns null instead of throwing when
the callback handler is not usable, which is what SaslClientFactory
specifies, and SaslClientAuthenticator falls back to the factory of its own
class loader when the registry yields no client. The registry is still
consulted first, so security.providers overrides keep taking precedence,
and the fallback only replaces a path that already fails today.
I would like to comment on that ticket with the analysis before opening a
pull request, which also needs an account.
The changes are here if anyone wants to look before the tickets exist:
https://github.com/seokmo-yoo-dev/kafka/pull/1
https://github.com/seokmo-yoo-dev/kafka/pull/2
Happy to adjust the approach on either one. Thanks for your time.
Seokmo Yoo