apache/druid · error · IllegalStateException

Not supported

Error message

Not supported

What it means

TypeStrategy.fromBytes(byte[]) is a default method that deserializes a base64-encoded byte array value; only COMPLEX types are expected to override it for the expression engine's decode_base64 function. The default implementation throws IllegalStateException('Not supported').

Solutions

  1. Only call fromBytes for types whose strategy implements it (COMPLEX types with byte-array support)
  2. Implement fromBytes in the custom complex type's TypeStrategy/Serde
  3. Avoid decode_base64 on unsupported column types in expressions

Example fix

// before
Object v = strategy.fromBytes(Base64.decode(encoded));
// after
if (strategy instanceof MyComplexStrategy) {
  Object v = strategy.fromBytes(Base64.decode(encoded));
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (strategy instanceof ByteDecodableStrategy) { value = ((ByteDecodableStrategy<?>) strategy).fromBytes(bytes); }

Type guard

boolean supportsFromBytes(TypeStrategy<?> s) { return s instanceof SomeComplexStrategy || s.getClass().getName().equals(KNOWN_IMPLEMENTING_CLASSES); } // no marker interface exists; check type docs

Try / catch

try { return strategy.fromBytes(bytes); } catch (IllegalStateException e) { return null; /* type does not support decode_base64 */ }

Prevention

When it happens

Trigger: Calling fromBytes on a primitive, array, or complex type strategy that does not implement it — e.g. evaluating decode_base64 on a column of a type whose strategy lacks the override.

Common situations: Running decode_base64 expressions on non-complex or unsupported complex columns; custom complex types whose serde does not implement fromBytes.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/segment/column/TypeStrategy.java:176

      return write(buffer, value, maxSizeBytes);
    }
    finally {
      buffer.position(oldPosition);
    }
  }

  /**
   * Translate raw byte array into a value. This is primarily useful for transforming self contained values that are
   * serialized into byte arrays, such as happens with 'COMPLEX' types which serialize to base64 strings in JSON
   * responses.
   *
   * 'COMPLEX' types should implement this method to participate in the expression systems built-in function
   * to deserialize base64 encoded values,
   * {@link org.apache.druid.math.expr.BuiltInExprMacros.ComplexDecodeBase64ExprMacro}.
   */
  default T fromBytes(byte[] value)
  {
    throw new IllegalStateException("Not supported");
  }

  /**
   * Whether the type is groupable or not. This is always true for all the primitive types, arrays, and nested arrays
   * therefore the SQL and the native layer might ignore this flag for those types. For complex types, this flag can be
   * true or false, depending on whether the semantics and implementation of the type naturally leads to groupability
   * or not. For example, it makes sense for JSON columns to be groupable, however there is little sense in grouping
   * sketches (before finalizing).
   * <p>
   * If a type is groupable, following statements MUST hold:
   * <p>
   * a. {@link #equals(Object, Object)} must be implemented. It should return true if and only if two objects are equal
   *    and can be grouped together.
   * <p>
   * b. {@link #hashCode(Object)} must be implemented, and must be consistent with equals. It should return a hashCode
   *    for the given object. For two objects that are equal, it must return the same hash value. For two objects that are
   *    not equal, it can return the same hash value (or not). A conscious effort must be made to minimise collisions between
   *    the hash values of two non-equal objects for faster grouping.

View on GitHub (pinned to 9b90983fd2)