quarkusio/quarkus · error · IllegalArgumentException
Use GeneratedServiceProviderBuildItem to register service pr
Error message
Use GeneratedServiceProviderBuildItem to register service providers instead of GeneratedResourceBuildItem, or use GeneratedResourceBuildItem.allowingMetaInfServices(...) if your ${name} resource is not a service provider What it means
GeneratedResourceBuildItem is for generated application resources; META-INF/services/ entries, however, are service provider registrations and must go through GeneratedServiceProviderBuildItem so Quarkus can index and handle them correctly. Since this guard was introduced, emitting a generated resource under META-INF/services/ through the plain resource item throws IllegalArgumentException, telling you which item to use instead.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/builditem/GeneratedResourceBuildItem.java:43
public GeneratedResourceBuildItem(String name, byte[] data) {
this(name, data, false);
}
/**
* @deprecated Use {@link GeneratedResourceBuildItem#GeneratedResourceBuildItem(String, byte[])} instead.
* If you want to serve static resources use
* {@link io.quarkus.vertx.http.deployment.spi.GeneratedStaticResourceBuildItem}
* instead.
*/
@Deprecated(since = "4.0", forRemoval = true)
public GeneratedResourceBuildItem(String name, byte[] data, boolean excludeFromDevCL) {
this(name, data, excludeFromDevCL, false);
}
private GeneratedResourceBuildItem(String name, byte[] data, boolean excludeFromDevCL,
boolean allowMetaInfServices) {
if (name.startsWith("META-INF/services/") && !allowMetaInfServices) {
throw new IllegalArgumentException(
"Use GeneratedServiceProviderBuildItem to register service providers instead of GeneratedResourceBuildItem, or use GeneratedResourceBuildItem.allowingMetaInfServices(...) if your "
+ name + " resource is not a service provider");
}
this.name = name;
this.data = data;
this.excludeFromDevCL = excludeFromDevCL;
}
/**
* Use only for {@code META-INF/services/} resources with a non-standard format incompatible with
* {@link GeneratedServiceProviderBuildItem}. Prefer {@link GeneratedServiceProviderBuildItem} for standard
* Java {@link java.util.ServiceLoader} registrations.
*/
public static GeneratedResourceBuildItem allowingMetaInfServices(String name, byte[] data) {
return new GeneratedResourceBuildItem(name, data, false, true);
}
public String getName() {View on GitHub (pinned to e1c734241f)
Solutions
- Replace the item with new GeneratedServiceProviderBuildItem(serviceInterfaceName, List.of(implementationClassNames)) and drop the manual descriptor bytes.
- If the resource genuinely is not a service provider but just happens to live under META-INF/services/, use GeneratedResourceBuildItem.allowingMetaInfServices(...) instead of the plain constructor.
- Update related build steps that consume the resource item so they consume the service provider item instead.
Example fix
// before
buildProducer.produce(new GeneratedResourceBuildItem(
"META-INF/services/com.acme.MySpi",
implClass.getBytes(StandardCharsets.UTF_8)));
// after
buildProducer.produce(new GeneratedServiceProviderBuildItem(
"com.acme.MySpi", List.of("com.acme.MySpiImpl"))); Defensive patterns
Strategy: validation
Validate before calling
void produceGenerated(BuildProducer<GeneratedResourceBuildItem> out, String name, byte[] data) {
if (name.startsWith("META-INF/services/")) {
throw new IllegalArgumentException("Use GeneratedServiceProviderBuildItem for " + name);
}
out.produce(new GeneratedResourceBuildItem(name, data));
} Type guard
boolean isServiceProviderResource(String name) {
return name != null && name.startsWith("META-INF/services/");
} Try / catch
try {
out.produce(new GeneratedResourceBuildItem(name, data));
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("GeneratedServiceProviderBuildItem")) {
String svc = name.substring("META-INF/services/".length());
serviceProviderProducer.produce(new GeneratedServiceProviderBuildItem(svc, List.of(implClassName)));
return;
}
throw e;
} Prevention
- Register ServiceLoader providers exclusively via GeneratedServiceProviderBuildItem
- Search your build steps for 'META-INF/services/' string literals during migration
- Use allowingMetaInfServices(...) only when the file under META-INF/services/ is genuinely not a provider descriptor
When it happens
Trigger: Producing new GeneratedResourceBuildItem("META-INF/services/io.quarkus...", bytes) in a build step without using GeneratedResourceBuildItem.allowingMetaInfServices(...) or switching to GeneratedServiceProviderBuildItem.
Common situations: Older extensions that predate the dedicated service-provider build item; code migrating from raw resource emission for ServiceLoader files; copy-pasted build-step code writing service descriptors.
Related errors
- Failed to open path tree with root %s
- Dev services for ${request.getName()} requires a startable s
- Name cannot start with '/':${name}
- The class (${name}) cannot be created during deployment.
- You're not expected to use the unnamed module as identifier
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/dff2f4b1c14adec0.
Report an issue: GitHub.