apache/druid · error · IllegalArgumentException

Value [%s] is not valid for property [%s], expected type [%s

Error message

Value [%s] is not valid for property [%s], expected type [%s]

What it means

Thrown by CatalogUtils.safeCast when a catalog table property value exists but cannot be cast to the expected type via type.cast(value), i.e. ClassCastException. It reports the offending value, property key, and expected type name so the misconfigured table definition can be corrected.

Source

Thrown at server/src/main/java/org/apache/druid/catalog/model/CatalogUtils.java:110

   */
  public static List<String> stringToList(String value)
  {
    if (value == null) {
      return null;
    }
    return Arrays.asList(value.split(",\\s*"));
  }

  public static <T> T safeCast(Object value, Class<T> type, String key)
  {
    if (value == null) {
      return null;
    }
    try {
      return type.cast(value);
    }
    catch (ClassCastException e) {
      throw new IAE("Value [%s] is not valid for property [%s], expected type [%s]",
          value,
          key,
          type.getSimpleName()
      );
    }
  }

  public static <T> T safeGet(Map<String, Object> map, String key, Class<T> type)
  {
    return safeCast(map.get(key), type, key);
  }

  public static long getLong(Map<String, Object> map, String key)
  {
    Object value = map.get(key);
    if (value == null) {
      return 0;
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Correct the table property value to the expected type (e.g. unquoted number for Long, JSON array of strings for string arrays)
  2. Inspect the persisted table definition and compare each property against the TableDefn schema
  3. If updating programmatically, wrap numbers in the exact expected boxed type (Long, not Integer)

Example fix

// before
{"targetLoadOnly": "true"}
// after
{"targetLoadOnly": true}
Defensive patterns

Strategy: type-guard

Validate before calling

if (value instanceof String && expected == Long.class) {
  // pre-coerce or reject: "123" will fail cast
}
if (expected == List.class && !(value instanceof List)) {
  throw new IllegalArgumentException("Property must be a JSON array");
}

Type guard

static <T> boolean isAssignable(Object value, Class<T> type) {
  return type.isInstance(value);
}
// usage: if (!isAssignable(props.get(key), Long.class)) fix before safeGet;

Try / catch

try {
  Long v = CatalogUtils.safeGet(props, "someLong", Long.class);
} catch (IllegalArgumentException e) {
  log.error("Bad property type: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling safeGet/getLong/getStringArray (or safeCast directly) on a table property whose stored value type differs from the expected one - e.g. a string '123' where a Long is expected, a scalar where List<String> is expected, or JSON deserialization yielding a different concrete type.

Common situations: Hand-edited catalog JSON where numbers are quoted as strings, schema changes between Druid versions altering a property's type, programmatic updates writing Integer where Long is required (Integer cannot be cast to Long).

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/74c88fe67424d9b2. Report an issue: GitHub.