quarkusio/quarkus · error · IllegalArgumentException

ETag was null

Error message

ETag was null

What it means

RequestImpl.evaluatePreconditions(EntityTag) throws IllegalArgumentException when the supplied EntityTag is null, as required by JAX-RS. Conditional request evaluation (If-Match/If-None-Match) cannot proceed without an ETag value.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/RequestImpl.java:103

            if (tag.equals(eTag) || tag.getValue().equals("*")) {
                match = true;
                break;
            }
        }
        if (match) {
            if ("GET".equals(httpMethod) || "HEAD".equals(httpMethod)) {
                return Response.notModified(eTag);
            }

            return Response.status(Response.Status.PRECONDITION_FAILED).tag(eTag);
        }
        return null;
    }

    @Override
    public Response.ResponseBuilder evaluatePreconditions(EntityTag eTag) {
        if (eTag == null)
            throw new IllegalArgumentException("ETag was null");
        Response.ResponseBuilder builder = null;
        List<String> ifMatch = requestContext.getHttpHeaders().getRequestHeaders().get(HttpHeaders.IF_MATCH);
        if (ifMatch != null && ifMatch.size() > 0) {
            builder = ifMatch(convertEtag(ifMatch), eTag);
        }
        if (builder == null) {
            List<String> ifNoneMatch = requestContext.getHttpHeaders().getRequestHeaders().get(HttpHeaders.IF_NONE_MATCH);
            if (ifNoneMatch != null && ifNoneMatch.size() > 0) {
                builder = ifNoneMatch(convertEtag(ifNoneMatch), eTag);
            }
        }
        if (builder != null) {
            builder.tag(eTag);
        }
        if (builder != null && varyHeader != null)
            builder.header(HttpHeaders.VARY, varyHeader);
        return builder;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the EntityTag is non-null before calling, computing a default one if caching is disabled.
  2. If the ETag is unknown, call the no-arg evaluatePreconditions() instead (which never throws).
  3. Null-check and skip conditional evaluation, returning a plain Response.

Example fix

// before
Response.ResponseBuilder rb = request.evaluatePreconditions(etag); // etag may be null
// after
Response.ResponseBuilder rb = etag != null
    ? request.evaluatePreconditions(etag)
    : request.evaluatePreconditions();
Defensive patterns

Strategy: type-guard

Validate before calling

if (etag == null) {
    return request.evaluatePreconditions(); // never throws
}

Type guard

boolean hasEtag(EntityTag t) {
    return t != null;
}

Try / catch

try {
    return request.evaluatePreconditions(etag);
} catch (IllegalArgumentException e) {
    return request.evaluatePreconditions();
}

Prevention

When it happens

Trigger: Calling request.evaluatePreconditions(EntityTag) with an EntityTag that is null — typically the result of a failed lookup or an uncomputed ETag passed straight through.

Common situations: ETag generated conditionally (only when caching enabled) and then passed unconditionally; refactoring where the ETag variable became nullable; reading an ETag from a store that returned null.

Related errors


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