KafkaException jdk.internal.loader.ClassLoaders can’t find org.apache.kafka.common.security.plain.PlainLoginModule
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
This Kafka exception usually means the client is configured to use SASL/PLAIN, but the runtime classpath does not contain the Kafka classes that implement that login module. In practice, the failure is almost always caused by a missing or mismatched Kafka client dependency rather than by the JAAS string itself.
What the Error Means
The class org.apache.kafka.common.security.plain.PlainLoginModule is part of the Kafka client libraries. When Kafka reads a SASL/PLAIN configuration like:
it tries to load that class at runtime. If the class loader cannot find it, Kafka throws the exception.
So the problem is not that the class name is wrong. The problem is that the JVM cannot see the jar that contains it.
The First Thing to Check
If you are writing a Java application, verify that kafka-clients is actually present at runtime.
Maven:
Gradle:
If the dependency is declared with the wrong scope, excluded transitively, or missing from the packaged application image, the class will not be available.
A Minimal Producer Example
The following configuration is valid only if the Kafka client jar is present:
If this fails with the class loader message, the next suspect is the runtime packaging, not the code syntax.
Common Real Causes
A frequent case is using Spring Boot or another framework where dependency versions are managed for you, then overriding one Kafka-related artifact manually. That can lead to an inconsistent classpath.
Another common case is shading or packaging a fat jar incorrectly. The dependency is present in the build but missing from the final executable artifact.
Containers also cause surprises. A local IDE run may work because the IDE includes the dependency, while the Docker image fails because the final copy step omitted some jars.
How to Debug It
Start with dependency inspection:
Maven:
Gradle:
Those commands help confirm whether kafka-clients is present and whether multiple versions are fighting each other.
If the dependency tree looks correct, inspect the actual packaged artifact or container image. The JVM only cares about what is present at runtime.
Do Not Misdiagnose JAAS Syntax
JAAS syntax errors can happen, but they usually produce different failures. If the exception explicitly says the class loader cannot find PlainLoginModule, the highest-probability diagnosis is still classpath or packaging.
That is why changing quotes, semicolons, or property names blindly often wastes time. Verify the dependency and runtime layout first.
Common Pitfalls
The biggest mistake is assuming a compile-time dependency guarantees runtime availability. In Java packaging, that is not always true.
Another problem is mixing incompatible Kafka versions across framework starters and direct dependencies. That can create subtle runtime failures even if the project compiles.
A third issue is setting sasl.mechanism=PLAIN without also including the right security protocol and credentials. That does not cause this specific class-not-found error, but it often appears immediately afterward once the classpath issue is fixed.
Summary
- '
PlainLoginModuleis provided by Kafka client libraries, not by the JDK.' - This exception usually means
kafka-clientsis missing or not packaged at runtime. - Check Maven or Gradle dependency trees before changing JAAS syntax.
- Inspect the final jar or container image, not just the local IDE classpath.
- After fixing the classpath, verify the rest of the SASL/PLAIN configuration normally.
Related reading
- KafkaIO checkpoint - how to commit offsets to Kafka
- Kafka.JS refuses to connect <<[BrokerPool] Failed to connect to seed broker, trying another broker from the list>>
- KafkaListener concurrency multiple topics
- KafkaListener Read from beginning every time
- KafkaListener in Unit test case does not consume from the container factory
- Key existence check in HashMap
- KafkaMessageListenerContainer vs ConcurrentMessageListenerContainer
- KafkaProducer Difference between `callback` and returned `Future`?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.