quarkusio/quarkus · error · IllegalArgumentException
Cannot consume/produce interface or abstract class build ite
Error message
Cannot consume/produce interface or abstract class build items
What it means
OpenApiServlet's doPost performs the same principal assertion for POSTs to /openapi/*: authentication must have succeeded or the servlet refuses with this error (actually an NPE from calling getName() on a null principal). It signals the POST was not authenticated by Elytron.
Source
Thrown at core/builder/src/main/java/io/quarkus/builder/BuildStepBuilder.java:260
Set<ItemId> getRealProduces() {
final LinkedHashMap<ItemId, Produce> map = new LinkedHashMap<>(produces);
map.entrySet().removeIf(e -> e.getValue().getConstraint() == Constraint.ORDER_ONLY);
return map.keySet();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BuildStep [");
builder.append(buildStep);
builder.append("]");
return builder.toString();
}
private void checkType(Class<?> type) {
int modifiers = type.getModifiers();
if (Modifier.isInterface(modifiers) || Modifier.isAbstract(modifiers)) {
throw new IllegalArgumentException("Cannot consume/produce interface or abstract class build items");
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Send valid basic-auth credentials with the POST request.
- Ensure quarkus.http.auth.permission policies require roles on /openapi/* POST and the realm is configured.
- Verify security constraints run container-managed authentication before doPost.
- Null-check getUserPrincipal() before calling getName().
Example fix
// before
if (req.getUserPrincipal().getName() == null) {
throw new RuntimeException("principal was null");
}
// after
if (req.getUserPrincipal() == null) {
throw new RuntimeException("principal was null");
} Defensive patterns
Strategy: try-catch
Validate before calling
Response check = given().header("tenantId", tenant).get("/fruits/" + id);
Assume.assumeFalse(check.getStatusCode() == 404); Try / catch
Response r = given().header("tenantId", tenant).get("/fruits/" + id);
if (r.getStatusCode() == 404) {
// handle not-found: seed data or pick a valid id
} else {
Fruit fruit = r.as(Fruit.class);
} Prevention
- Seed MariaDB test data per tenant before assertions
- Never reuse ids across environments or tenants
- Assert status code before deserializing the body
- Send the tenant header consistently (RestAssured filter helps)
When it happens
Trigger: POST to /openapi/* without valid credentials or with a failed auth mechanism, making req.getUserPrincipal() null before .getName() is called.
Common situations: Missing Authorization header on POST; permissive auth policy for /openapi/*; elytron properties realm misconfigured; token/session expired mid-test.
Related errors
- Build step '%s' does not produce any build item and thus wil
- No producers for required item %s, step builder used: %s
- cycle detection failure report (dynamic CycleBuildException
- principal was null
- Unsupported value type: %s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/764aef02c5585933.
Report an issue: GitHub.