quarkusio/quarkus · error · IllegalArgumentException

Last modified was null

Error message

Last modified was null

What it means

RequestImpl.evaluatePreconditions(Date, EntityTag) throws IllegalArgumentException when lastModified is null. The two-argument overload requires both a timestamp and an ETag to evaluate all conditional headers.

Source

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

        if (ifModifiedSince != null && (!isRfc7232preconditions() || (!headers.containsKey(HttpHeaders.IF_NONE_MATCH)))) {
            builder = ifModifiedSince(ifModifiedSince, lastModified);
        }
        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. Compute a valid lastModified value (entity update time, file mtime) before the call.
  2. If only the ETag is known, use the single-arg evaluatePreconditions(EntityTag) overload.
  3. Null-check and delegate to the no-arg overload when metadata is unavailable.

Example fix

// before
return request.evaluatePreconditions(lastModified, etag);
// after
if (lastModified == null) {
    return request.evaluatePreconditions(etag);
}
return request.evaluatePreconditions(lastModified, etag);
Defensive patterns

Strategy: type-guard

Validate before calling

if (lastModified == null || etag == null) {
    return lastModified == null && etag == null
        ? request.evaluatePreconditions()
        : (lastModified == null ? request.evaluatePreconditions(etag)
                                : request.evaluatePreconditions(lastModified));
}

Type guard

boolean preconditionable(Date lm, EntityTag t) {
    return lm != null && t != null;
}

Try / catch

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

Prevention

When it happens

Trigger: Calling the (Date, EntityTag) overload with a null lastModified, e.g. when the entity's modification date could not be loaded.

Common situations: Resource without stored modification metadata; date initialized lazily and never set; passing a computed date that failed to parse from a header or database value.

Related errors


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