google/gson · error · IllegalArgumentException

The date pattern ' ' is not valid

Error message

The date pattern '${pattern}' is not valid

What it means

Thrown by GsonBuilder.setDateFormat(String) when the pattern cannot be understood by SimpleDateFormat (its constructor raises IllegalArgumentException). Gson validates eagerly by attempting new SimpleDateFormat(pattern) so that an invalid pattern fails at configuration time rather than during the first (de)serialization. The original cause is chained.

Solutions

  1. Use a pattern valid for java.text.SimpleDateFormat, e.g. "yyyy-MM-dd'T'HH:mm:ss.SSSZ".
  2. Remember SimpleDateFormat pattern letters differ from java.time: 'y' year, 'M' month, 'd' day, 'H' hour, 'm' minute, 's' second, 'S' millis, 'Z'/'X' timezone.
  3. Escape literal text in single quotes, e.g. "yyyy-MM-dd'T'HH:mm:ss".
  4. Test the pattern with new SimpleDateFormat(pattern) in isolation to get a precise error.

Example fix

// before
builder.setDateFormat("yyyy-LL-dd"); // 'L' invalid for SimpleDateFormat

// after
builder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the pattern up front with the same engine Gson uses
try {
  new SimpleDateFormat(pattern);
} catch (IllegalArgumentException ex) {
  throw new IllegalArgumentException("Bad date pattern: " + pattern, ex);
}
builder.setDateFormat(pattern);

Try / catch

try { builder.setDateFormat(pattern); }
catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("The date pattern")) { /* fix pattern or fall back to default */ }
  else throw e;
}

Prevention

When it happens

Trigger: Pattern with illegal pattern letters (e.g. "YYYY-LL-DD" instead of "yyyy-MM-dd"); unterminated quoted text ("'abc"); unknown letters in non-lenient mode; empty or null token confusion; typo in pattern characters.

Common situations: Copy-pasting a DateTimeFormatter pattern (which uses different letters than SimpleDateFormat, e.g. 'u' vs 'y'); locale-specific patterns with unescaped text; migrating from java.time patterns; config typos.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/8c9b86a6fe1575d3. Report an issue: GitHub.

Appendix: source

Thrown at gson/src/main/java/com/google/gson/GsonBuilder.java:645

   *
   * <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
   * class. See the documentation in {@link SimpleDateFormat} for more information on valid date and
   * time patterns.
   *
   * @param pattern the pattern that dates will be serialized/deserialized to/from; can be {@code
   *     null} to reset the pattern
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
   * @throws IllegalArgumentException if the pattern is invalid
   * @since 1.2
   */
  @CanIgnoreReturnValue
  public GsonBuilder setDateFormat(String pattern) {
    if (pattern != null) {
      try {
        SimpleDateFormat unused = new SimpleDateFormat(pattern);
      } catch (IllegalArgumentException e) {
        // Throw exception if it is an invalid date format
        throw new IllegalArgumentException("The date pattern '" + pattern + "' is not valid", e);
      }
    }
    this.datePattern = pattern;
    return this;
  }

  /**
   * Configures Gson to serialize {@code Date} objects according to the date style value provided.
   * You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
   * invocation will be used to decide the serialization format. This method leaves the current
   * 'time style' unchanged.
   *
   * <p>Note that this style value should be one of the predefined constants in the {@link
   * DateFormat} class, such as {@link DateFormat#MEDIUM}. See the documentation of the {@link
   * DateFormat} class for more information on the valid style constants.
   *
   * @deprecated Counterintuitively, despite this method taking only a 'date style' Gson will use a
   *     format which includes both date and time, with the 'time style' being the last value set by

View on GitHub (pinned to 310ac341f2)