jwtk/jjwt · critical · UnavailableImplementationException
Unable to find an implementation for ${spi} using java.util.
Error message
Unable to find an implementation for ${spi} using java.util.ServiceLoader. Ensure you include a backing implementation .jar in the classpath, for example jjwt-jackson.jar, jjwt-gson.jar or jjwt-orgjson.jar, or your own .jar for custom implementations. What it means
Services.loadFirst uses java.util.ServiceLoader to locate a runtime implementation of a JJWT SPI (e.g. Serializer/Deserializer). When no provider is registered on the classpath it throws UnavailableImplementationException with a message instructing the developer to add a backing implementation jar such as jjwt-jackson, jjwt-gson, or jjwt-orgjson.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/lang/Services.java:99
Assert.notNull(spi, "Service interface cannot be null.");
Object obj = SERVICES.get(spi);
if (obj != null) {
return Assert.isInstanceOf(spi, obj, "Unexpected cached service implementation type.");
}
return null;
}
private static <T> T loadFirst(Class<T> spi) {
for (ClassLoaderAccessor accessor : CLASS_LOADER_ACCESSORS) {
ServiceLoader<T> loader = ServiceLoader.load(spi, accessor.getClassLoader());
Assert.stateNotNull(loader, "JDK ServiceLoader#load should never return null.");
Iterator<T> i = loader.iterator();
Assert.stateNotNull(i, "JDK ServiceLoader#iterator() should never return null.");
if (i.hasNext()) {
return i.next();
}
}
throw new UnavailableImplementationException(spi);
}
/**
* Clears internal cache of service singletons. This is useful when testing, or for applications that dynamically
* change classloaders.
*/
public static void reload() {
SERVICES.clear();
}
private interface ClassLoaderAccessor {
ClassLoader getClassLoader();
}
}
View on GitHub (pinned to fb71496164)
Solutions
- Add a runtime implementation dependency, e.g. implementation 'io.jsonwebtoken:jjwt-jackson:0.12.x' (or jjwt-gson / jjwt-orgjson).
- Verify the jar's META-INF/services files are intact if you shade/repackage dependencies.
- Ensure the ServiceLoader-visible classloader includes the implementation jar (check runtime vs. compile classpath).
Example fix
// before (build.gradle) implementation 'io.jsonwebtoken:jjwt-api:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' // after implementation 'io.jsonwebtoken:jjwt-api:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6'
Defensive patterns
Strategy: try-catch
Validate before calling
// fails fast at startup if no JSON implementation is on the classpath
static {
try {
io.jsonwebtoken.impl.lang.Services.get(io.jsonwebtoken.io.Serializer.class);
} catch (io.jsonwebtoken.lang.Classes.UnknownClassException | RuntimeException e) {
throw new IllegalStateException(
"No JJWT JSON implementation found. Add jjwt-jackson, jjwt-gson or jjwt-orgjson to the runtime classpath.", e);
}
} Try / catch
try {
String jwt = Jwts.builder()...compact();
} catch (io.jsonwebtoken.lang.Classes.UnknownClassException | io.jsonwebtoken.io.SerializationException e) {
throw new IllegalStateException("Missing JJWT serializer implementation; add jjwt-jackson/jjwt-gson/jjwt-orgjson", e);
} Prevention
- Always declare jjwt-api + jjwt-impl + one implementation (jjwt-jackson/gson/orgjson) together
- Smoke-test JWT creation at application startup to fail fast on missing implementations
- If shading jars, keep META-INF/services entries intact (ServicesResourceTransformer etc.)
When it happens
Trigger: Calling Jwts.builder().serializeTo(...) / Jwts.parser()... on the classpath containing only jjwt-api (and jjwt-impl) without a JSON serializer implementation.
Common situations: Adding jjwt-api and jjwt-impl dependencies but forgetting jjwt-jackson (or gson/orgjson); shaded/Thin classpaths that dropped META-INF/services entries; runtime classpath differing from the compile-time one.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Unable to load class named [${fqcn}] from the thread context
- Unable to invoke class method ${fqcn}#${methodName}. Ensure
- Unable to invoke class method ${clazzName}#${methodName}. En
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/31fd473552830585.
Report an issue: GitHub.