apache/seatunnel · error · UnsupportedOperationException

Avro format doesn't support non-string as key type of map. T

Error message

Avro format doesn't support non-string as key type of map. The key type is: ${sqlType}

What it means

Avro map schemas require string keys, so when extracting the value type for a MAP field, extractValueTypeToAvroMap() verifies the SeaTunnel map's key type is STRING. Any other key type throws UnsupportedOperationException with this message. Only the value type is returned for the Avro map item schema.

Source

Thrown at seatunnel-connectors-v2/connector-hudi/src/main/java/org/apache/seatunnel/connectors/seatunnel/hudi/sink/convert/AvroSchemaConverter.java:175

                Schema array =
                        SchemaBuilder.builder()
                                .array()
                                .items(convertToSchema(arrayType.getElementType(), rowName, true));
                return nullableSchema(array);
            default:
                throw new UnsupportedOperationException(
                        "Unsupported to derive Schema for type: " + dataType);
        }
    }

    public static SeaTunnelDataType<?> extractValueTypeToAvroMap(SeaTunnelDataType<?> type) {
        SeaTunnelDataType<?> keyType;
        SeaTunnelDataType<?> valueType;
        MapType<?, ?> mapType = (MapType<?, ?>) type;
        keyType = mapType.getKeyType();
        valueType = mapType.getValueType();
        if (keyType.getSqlType() != SqlType.STRING) {
            throw new UnsupportedOperationException(
                    "Avro format doesn't support non-string as key type of map. "
                            + "The key type is: "
                            + keyType.getSqlType());
        }
        return valueType;
    }

    /** Returns schema with nullable true. */
    private static Schema nullableSchema(Schema schema) {
        return Schema.createUnion(SchemaBuilder.builder().nullType(), schema);
    }

    private static int computeMinBytesForDecimalPrecision(int precision) {
        int numBytes = 1;
        while (Math.pow(2.0, 8 * numBytes - 1) < Math.pow(10.0, precision)) {
            numBytes += 1;
        }
        return numBytes;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Transform the map so its keys are STRING (rebuild the map field with string keys in an upstream transform).
  2. Serialize the map to a JSON string column before writing to Hudi.
  3. If key semantics don't matter, drop the field before the sink.

Example fix

// before
MapType(INT, STRING) written to Hudi sink

// after — convert to string-keyed map (or JSON string)
MapType(STRING, STRING) written to Hudi sink
Defensive patterns

Strategy: validation

Validate before calling

schema.toPhysicalRowDataType().getChildren().stream()
    .filter(t -> t instanceof MapType)
    .map(t -> (MapType<?, ?>) t)
    .forEach(m -> {
        if (m.getKeyType().getSqlType() != SqlType.STRING)
            throw new IllegalArgumentException("map key must be STRING: " + m);
    });

Type guard

static boolean hasStringMapKeys(SeaTunnelDataType<?> t) {
    return !(t instanceof MapType)
        || ((MapType<?, ?>) t).getKeyType().getSqlType() == SqlType.STRING;
}

Try / catch

try {
    Schema s = AvroSchemaConverter.convertToSchema(rowType, "rowName");
} catch (UnsupportedOperationException e) {
    if (e.getMessage().contains("non-string as key type of map")) {
        // rebuild the field with STRING keys or serialize to JSON
    } else throw e;
}

Prevention

When it happens

Trigger: A SeaTunnel schema containing a MapType whose keyType's SqlType is not STRING (e.g. MAP<INT,STRING> or MAP<LONG,...>) reaching the Hudi sink schema conversion.

Common situations: Sources with non-string-keyed maps (e.g. Protobuf map<uint32,string>, Parquet/Avro maps with integral keys) fed directly to the Hudi sink; assuming automatic key coercion.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/216ef2e774f4f6b2. Report an issue: GitHub.