quarkusio/quarkus · error · java.lang.IllegalArgumentException
Cannot resolve schema with refs
Error message
Cannot resolve schema with refs
What it means
During native-image substitution, Quarkus replaces the Confluent Schema Registry client's schema-parsing path with a local fallback. When no client is configured and there are schema references, the substituted code cannot resolve the referenced schemas, so it throws. The library throws this because resolving refs requires the schema registry client, which is absent.
Source
Thrown at extensions/schema-registry/confluent/json-schema/runtime/src/main/java/io/quarkus/confluent/registry/json/runtime/graal/ConfluentJsonSubstitutions.java:52
}
Class<?> cls = object.getClass();
//We only support the scenario of having the schema defined in the annotation in the java bean, since it does not rely on outdated libraries.
if (cls.isAnnotationPresent(Schema.class)) {
Schema schema = cls.getAnnotation(Schema.class);
List<SchemaReference> references = Arrays.stream(schema.refs())
.map(new Function<io.confluent.kafka.schemaregistry.annotations.SchemaReference, SchemaReference>() {
@Override
public SchemaReference apply(
io.confluent.kafka.schemaregistry.annotations.SchemaReference schemaReference) {
return new SchemaReference(schemaReference.name(), schemaReference.subject(),
schemaReference.version());
}
})
.collect(Collectors.toList());
if (client == null) {
if (!references.isEmpty()) {
throw new IllegalArgumentException("Cannot resolve schema " + schema.value()
+ " with refs " + references);
}
return new JsonSchema(schema.value());
} else {
return (JsonSchema) client.parseSchema(JsonSchema.TYPE, schema.value(), references)
.orElseThrow(new Supplier<IOException>() {
@Override
public IOException get() {
return new IOException("Invalid schema " + schema.value()
+ " with refs " + references);
}
});
}
}
return null;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Add the Confluent Schema Registry client dependency and configure quarkus.registry.confluent.schema-certification.url / registry client so the client is non-null
- Avoid schema references in the JSON Schema subject, or inline the referenced schemas ($defs) into a single self-contained schema
- If references are unavoidable, ensure the registries client (apicurio-registry-schema-registry-json-serde with client support) is used rather than the substitution fallback
- Check that the serializer/deserializer config points at the correct Schema Registry URL and the referenced schemas are registered there
Example fix
// before (application.properties)
# no registry client configured
mp.messaging.connector.smallrye-kafka.schema.registry.url=http://localhost:8081
// after
quarkus.registry.confluent.schema-certification.url=http://localhost:8081
quarkus.apicurio-registry.json.confluent-id-strategy=Legacy4Byte
# or inline refs:
// before: {"$ref":"other.schema.json"}
// after: {"$defs": {"Other": {...}}, "properties": {"o": {"$ref":"#/$defs/Other"}}} Defensive patterns
Strategy: validation
Validate before calling
if (schema.getReferences() != null && !schema.getReferences().isEmpty()
&& registryClient == null) {
throw new IllegalStateException(
"JSON schema " + schema.value() + " has references but no registry client is configured; "
+ "add the Confluent registry client dependency or inline the referenced schemas.");
} Type guard
boolean isResolvable(JsonSchema schema) {
return schema.getReferences() == null
|| schema.getReferences().isEmpty()
|| registryClient != null;
} Prevention
- Keep JSON Schemas self-contained (inline $defs) when possible
- Verify registry client config (quarkus.registry.confluent.*) before deploying to native
- Test schema resolution in a native-image integration test, not just JVM mode
- Confirm referenced schemas are actually registered in the Schema Registry subject
When it happens
Trigger: Building/running a native image (or using the Confluent JSON Schema substitution path) while deserializing/serializing JSON Schema messages whose schema declares references ($ref/$defs to other registered schemas) with quarkus.registry.confluent.* client disabled or not on the classpath.
Common situations: Avro/JSON Schema topics using schema references produced via Confluent SR ('register schema with references'); the app only declares quarkus-apicurio-registry-avro or forgot the confluent registry dependency; refs work in JVM mode but fail in native mode.
Related errors
- JDK HTTP adapter is not available in native mode. Please use
- service interface name cannot be null or blank
- service interface descriptor file path cannot be null
- Could not read class path resources having path '${resourceP
- The serviceDescriptorFile interface cannot be blank
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0f513f3ae9619626.
Report an issue: GitHub.