quarkusio/quarkus · error · IllegalStateException
Cannot instantiate JSON-B component:
Error message
Cannot instantiate JSON-B component:
What it means
QuarkusJsonbComponentInstanceCreator resolves JSON-B components (Jsonb, JsonbBuilder, custom components) from CDI; fallbackCreate is a last resort that tries a no-arg constructor. When reflection-based instantiation fails (abstract class, missing no-arg constructor, throwing constructor, illegal access), it throws IllegalStateException 'Cannot instantiate JSON-B component: <class>'. This almost always means a custom JSON-B component was registered that Quarkus cannot construct.
Source
Thrown at extensions/jsonb/runtime/src/main/java/io/quarkus/jsonb/QuarkusJsonbComponentInstanceCreator.java:57
ArcContainer container = Arc.container();
if (container == null) { // this class can be used in unit tests where Arc obviously doesn't run
return fallbackCreate(componentClass);
}
InstanceHandle<T> beanHandle = container.instance(componentClass);
if (beanHandle.isAvailable()) {
beanHandles.add(beanHandle);
return beanHandle.get();
}
return fallbackCreate(componentClass);
});
}
private <T> Object fallbackCreate(Class<T> componentClass) {
try {
return componentClass.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new IllegalStateException("Cannot instantiate JSON-B component: " + componentClass, e);
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Give the component class a public no-arg constructor and make it concrete (non-abstract)
- Register the component instance via JsonbConfig.withSerializers/withAdapters using an explicit instance instead of relying on class-based registration
- Make the component a CDI bean and configure it through Quarkus's JSON-B CDI integration instead of the fallback path
- Check the cause chain for the exception thrown inside the component constructor
Example fix
// before
public class ZonedDateTimeSerializer implements JsonbSerializer<ZonedDateTime> {
private final ZoneId zone; // no no-arg ctor
...
}
// after
public class ZonedDateTimeSerializer implements JsonbSerializer<ZonedDateTime> {
public ZonedDateTimeSerializer() { this.zone = ZoneId.systemDefault(); }
...
} Defensive patterns
Strategy: validation
Validate before calling
static <T> boolean canInstantiate(Class<T> c) {
try {
c.getDeclaredConstructor().newInstance();
return true;
} catch (ReflectiveOperationException | RuntimeException e) {
return false;
}
} Type guard
static <T> boolean hasPublicNoArgCtor(Class<T> c) {
try { return java.lang.reflect.Modifier.isPublic(c.getModifiers())
&& !java.lang.reflect.Modifier.isAbstract(c.getModifiers())
&& c.getDeclaredConstructor().getParameterCount() == 0; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
// Quarkus JSON-B setup that triggers component creation
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Cannot instantiate JSON-B component:")) {
log.errorf(e.getCause(), "Fix component %s: needs public no-arg ctor or explicit registration", e.getMessage());
} else throw e;
} Prevention
- Give JSON-B components a public no-arg constructor and keep them concrete
- Register instances explicitly via JsonbConfig.withSerializers/withAdapters instead of relying on fallback reflection
- Keep constructors side-effect free (no config/file reads that can throw)
- Add a unit test that instantiates every registered JSON-B component reflectively
When it happens
Trigger: Registering a custom JsonbConfig component, JsonbAdapter, JsonbSerializer/Deserializer, or instance creator class that has no public no-arg constructor, is abstract, or whose constructor throws; and the component was not available as a CDI bean so the fallback path was used.
Common situations: User adds a JSON-B serializer/adapter class with only constructor arguments and registers it globally; upgrading Quarkus/Yasson where the component resolution path changed; a component class throwing inside its constructor (e.g. reading a missing config).
Related errors
- Cache key generator instantiation failed
- Unable to instantiate the class:
- Couldn't extract all parameters information for constructor
- Multiple @Inject constructors on ${theClass}
- Failed to set dev services config
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e295e83743f7ed0a.
Report an issue: GitHub.