quarkusio/quarkus · error · IllegalArgumentException
etag was null
Error message
etag was null
What it means
RequestImpl.evaluatePreconditions(Date, EntityTag) throws IllegalArgumentException when the EntityTag argument is null. Both parameters are mandatory in the two-argument overload per the JAX-RS specification.
Source
Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/RequestImpl.java:179
}
if (builder == null) {
String ifUnmodifiedSince = headers.getFirst(HttpHeaders.IF_UNMODIFIED_SINCE);
if (ifUnmodifiedSince != null && (!isRfc7232preconditions() || (!headers.containsKey(HttpHeaders.IF_MATCH)))) {
builder = ifUnmodifiedSince(ifUnmodifiedSince, lastModified);
}
}
if (builder != null && varyHeader != null)
builder.header(HttpHeaders.VARY, varyHeader);
return builder;
}
@Override
public Response.ResponseBuilder evaluatePreconditions(Date lastModified, EntityTag eTag) {
if (lastModified == null)
throw new IllegalArgumentException("Last modified was null");
if (eTag == null)
throw new IllegalArgumentException("etag was null");
Response.ResponseBuilder rtn = null;
Response.ResponseBuilder lastModifiedBuilder = evaluatePreconditions(lastModified);
Response.ResponseBuilder etagBuilder = evaluatePreconditions(eTag);
if (lastModifiedBuilder == null && etagBuilder == null)
rtn = null;
else if (lastModifiedBuilder != null && etagBuilder == null)
rtn = lastModifiedBuilder;
else if (lastModifiedBuilder == null && etagBuilder != null)
rtn = etagBuilder;
else {
rtn = lastModifiedBuilder;
rtn.tag(eTag);
}
if (rtn != null && varyHeader != null)
rtn.header(HttpHeaders.VARY, varyHeader);
return rtn;
}
View on GitHub (pinned to e1c734241f)
Solutions
- Always build a non-null EntityTag (e.g. hash of the representation) before this call.
- If only lastModified is known, use the single-arg evaluatePreconditions(Date) overload.
- Branch on the null ETag and call the appropriate overload or the no-arg variant.
- Note: the thrown message is the lowercase 'etag was null', distinct from 'ETag was null' of the single-arg overload.
Example fix
// before
return request.evaluatePreconditions(lastModified, etag);
// after
if (etag == null) {
return request.evaluatePreconditions(lastModified);
}
return request.evaluatePreconditions(lastModified, etag); Defensive patterns
Strategy: type-guard
Validate before calling
if (etag == null) {
return request.evaluatePreconditions(lastModified);
} Type guard
boolean hasEtag(EntityTag t) {
return t != null;
} Try / catch
try {
return request.evaluatePreconditions(lastModified, etag);
} catch (IllegalArgumentException e) {
return request.evaluatePreconditions(lastModified);
} Prevention
- Generate an EntityTag unconditionally for cached resources
- Use the Date-only overload when no ETag exists
- Never chain Optional.get() results into this API
When it happens
Trigger: Calling the (Date, EntityTag) overload with a null EntityTag, usually because ETag generation is conditional in the application code.
Common situations: Caching disabled in some environments so no ETag is produced; a getter returning null for weak entities; refactor changed an Optional-style ETag into a bare null argument.
Related errors
- ETag was null
- Param cannot be null
- Last modified was null
- retrieving all roles not supported when JAX-RS security cont
- More than one Application class: ${applications}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d51b72a3ae9558d9.
Report an issue: GitHub.