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

  1. Add a runtime implementation dependency, e.g. implementation 'io.jsonwebtoken:jjwt-jackson:0.12.x' (or jjwt-gson / jjwt-orgjson).
  2. Verify the jar's META-INF/services files are intact if you shade/repackage dependencies.
  3. 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

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


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/31fd473552830585. Report an issue: GitHub.