apache/druid · error · UnsupportedOperationException

Avro + nested tree extraction not supported

Error message

Avro + nested tree extraction not supported

What it means

Avro flattening can extract a single root field by name, but traversing nested JSON-tree node paths (nodes.size() > 1) is not implemented for Avro records, so makeJsonTreeExtractor throws UnsupportedOperationException for nested paths.

Source

Thrown at extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/AvroFlattenerMaker.java:171

  {
    final JsonPath jsonPath = JsonPath.compile(expr);
    return record -> transformValue(jsonPath.read(record, jsonPathConfiguration));
  }

  @Override
  public Function<GenericRecord, Object> makeJsonQueryExtractor(final String expr)
  {
    throw new UnsupportedOperationException("Avro + JQ not supported");
  }

  @Override
  public Function<GenericRecord, Object> makeJsonTreeExtractor(List<String> nodes)
  {
    if (nodes.size() == 1) {
      return (GenericRecord record) -> getRootField(record, nodes.get(0));
    }

    throw new UnsupportedOperationException("Avro + nested tree extraction not supported");
  }

  @Override
  public JsonProvider getJsonProvider()
  {
    return avroJsonProvider;
  }

  @Override
  public Object finalizeConversionForMap(Object o)
  {
    return transformValue(o);
  }

  private Object transformValue(final Object field)
  {
    if (fromPigAvroStorage && field instanceof GenericArray) {
      return Lists.transform((List) field, item -> String.valueOf(((GenericRecord) item).get(0)));

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use the "jsonPath" flattener with a $.a.b.c path expression instead of the tree flattener for nested fields.
  2. Flatten only root fields (single-node tree expressions) or reference Avro sub-fields via jsonPath.
  3. Restructure the ingestion: decode Avro to JSON first, then apply nested tree extraction on the JSON format.

Example fix

// before
{"flattener": {"type": "json", "fieldName": "event.a.b"}}
// after
{"flattener": {"type": "jsonPath", "expr": "$.event.a.b"}}
Defensive patterns

Strategy: validation

Validate before calling

if ("json".equals(flattener.getType()) && expr.split("\\.").length > 1) {
  throw new IllegalArgumentException("Nested tree extraction unsupported for Avro; use jsonPath");
}

Type guard

boolean isSimpleTreeExpr(FlattenerSpec f) {
  return !"json".equals(f.getType()) || f.getFieldName().indexOf('.') < 0;
}

Try / catch

try {
  extractor = flattenerMaker.makeJsonTreeExtractor(nodes);
} catch (UnsupportedOperationException e) {
  extractor = flattenerMaker.makeJsonPropertyExtractor(joinWithDollarPath(nodes));
}

Prevention

When it happens

Trigger: A flattenSpec with "type": "json" (tree) flattener and an expression containing multiple path nodes (nested extraction, e.g. "a.b.c") applied to an Avro input format — the first single-node case works, anything deeper throws.

Common situations: Reusing nested-tree flatten specs designed for JSON data sources against Avro streams; users expecting JmesPath/tree navigation inside Avro unions/records.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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