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

  1. Always build a non-null EntityTag (e.g. hash of the representation) before this call.
  2. If only lastModified is known, use the single-arg evaluatePreconditions(Date) overload.
  3. Branch on the null ETag and call the appropriate overload or the no-arg variant.
  4. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/d51b72a3ae9558d9. Report an issue: GitHub.