quarkusio/quarkus · error · RuntimeException

'java.time.Instant' types must not be annotated with '@DateF

Error message

'java.time.Instant' types must not be annotated with '@DateFormat'

What it means

java.time.Instant parameters use a fixed InstantParamConverter based on standard ISO-8601 parsing, so @DateFormat (which configures a DateTimeFormatter) is meaningless for them. If @DateFormat is present on an Instant parameter, determineTemporalConverter throws this RuntimeException at deployment.

Source

Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java:619

        String dateTimeFormatterProviderClassName = null;

        AnnotationInstance dateFormatInstance = parameterAnnotations.get(DATE_FORMAT);

        if (dateFormatInstance != null) {
            AnnotationValue formatValue = dateFormatInstance.value("pattern");
            if (formatValue != null) {
                format = formatValue.asString();
            }

            AnnotationValue dateTimeFormatterProviderValue = dateFormatInstance.value("dateTimeFormatterProvider");
            if (dateTimeFormatterProviderValue != null) {
                dateTimeFormatterProviderClassName = dateTimeFormatterProviderValue.asClass().name().toString();
            }
        }

        if (INSTANT.equals(paramType)) {
            if (dateFormatInstance != null) {
                throw new RuntimeException(contextualizeErrorMessage(
                        "'java.time.Instant' types must not be annotated with '@DateFormat'",
                        currentMethodInfo));
            }
            return new InstantParamConverter.Supplier();
        }

        if ((format != null) && (dateTimeFormatterProviderClassName != null)) {
            throw new RuntimeException(contextualizeErrorMessage(
                    "Using both 'format' and 'dateTimeFormatterProvider' is not allowed when using '@DateFormat'",
                    currentMethodInfo));
        } else if ((format == null) && (dateTimeFormatterProviderClassName == null) && (dateFormatInstance != null)) {
            throw new RuntimeException(contextualizeErrorMessage(
                    "One of 'format' or 'dateTimeFormatterProvider' must be set when using '@DateFormat'", currentMethodInfo));
        }

        if (LOCAL_DATE.equals(paramType)) {
            return new LocalDateParamConverter.Supplier(format, dateTimeFormatterProviderClassName);
        } else if (LOCAL_DATE_TIME.equals(paramType)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove @DateFormat from the Instant parameter; Instant parses its standard ISO-8601 form.
  2. If custom formats are needed, switch to String or LocalDateTime/OffsetDateTime and convert manually.
  3. For stricter validation, accept String, parse with DateTimeFormatter.ISO_INSTANT, and map failures to 400.

Example fix

// before
@QueryParam("since")
@DateFormat(format = "yyyy-MM-dd")
Instant since;

// after
@QueryParam("since")
Instant since; // ISO-8601 only
Defensive patterns

Strategy: validation

Validate before calling

for (java.lang.reflect.Field f : Resource.class.getDeclaredFields()) {
    if (f.getType() == java.time.Instant.class
        && f.isAnnotationPresent(org.jboss.resteasy.reactive.DateFormat.class)) {
        throw new IllegalStateException("@DateFormat is not allowed on Instant fields: " + f.getName());
    }
}

Prevention

When it happens

Trigger: @QueryParam("since") @DateFormat(...) Instant since — any Instant parameter/field carrying @DateFormat.

Common situations: Copy-pasting a LocalDateTime parameter declaration and changing the type to Instant while keeping @DateFormat; wanting custom offset parsing for Instant.

Related errors


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