apache/flink · error · UnsupportedOperationException

Unsupported type: %s

Error message

Unsupported type: %s

What it means

Thrown by CsvToRowDataConverters.createConverter when a column's LogicalTypeRoot is MAP, MULTISET, or RAW: the CSV deserializer has converters for primitives, arrays, and rows but none for map-like or raw types, so it raises UnsupportedOperationException at converter-construction time (table/plan validation of the csv format source).

Source

Thrown at flink-formats/flink-csv/src/main/java/org/apache/flink/formats/csv/CsvToRowDataConverters.java:184

            case DOUBLE:
                return this::convertToDouble;
            case CHAR:
            case VARCHAR:
                return this::convertToString;
            case BINARY:
            case VARBINARY:
                return this::convertToBytes;
            case DECIMAL:
                return createDecimalConverter((DecimalType) type);
            case ARRAY:
                return createArrayConverter((ArrayType) type);
            case ROW:
                return createRowConverter((RowType) type, false);
            case MAP:
            case MULTISET:
            case RAW:
            default:
                throw new UnsupportedOperationException("Unsupported type: " + type);
        }
    }

    private boolean convertToBoolean(JsonNode jsonNode) {
        if (jsonNode.isBoolean()) {
            // avoid redundant toString and parseBoolean, for better performance
            return jsonNode.asBoolean();
        } else {
            return Boolean.parseBoolean(jsonNode.asText().trim());
        }
    }

    private int convertToInt(JsonNode jsonNode) {
        if (jsonNode.canConvertToInt()) {
            // avoid redundant toString and parseInt, for better performance
            return jsonNode.asInt();
        } else {
            return Integer.parseInt(jsonNode.asText().trim());

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Remove the MAP/MULTISET/RAW column from the CSV table, or declare it as STRING and parse downstream.
  2. Switch the format to 'json' which supports MAP/MULTISET.
  3. Ensure UDF-derived columns are cast to supported SQL types before hitting the csv source contract.

Example fix

-- before
CREATE TABLE t (id INT, props MAP<STRING,STRING>) WITH ('format'='csv', ...);

-- after
CREATE TABLE t (id INT, props STRING) WITH ('format'='csv', ...);
Defensive patterns

Strategy: type-guard

Validate before calling

// Before creating the table/deserializer:
static boolean csvDeserializable(LogicalType t) {
    LogicalTypeRoot r = t.getTypeRoot();
    return r != LogicalTypeRoot.MAP && r != LogicalTypeRoot.MULTISET && r != LogicalTypeRoot.RAW;
}
// fail fast in a unit test over the table schema

Type guard

static boolean isCsvReadableColumn(LogicalType t) {
    switch (t.getTypeRoot()) {
        case MAP: case MULTISET: case RAW: return false;
        default: return true;
    }
}

Prevention

When it happens

Trigger: CREATE TABLE ... WITH ('format'='csv') whose schema contains MAP<..,..>, MULTISET<..>, or a RAW-typed column; the converter lookup happens while the deserialization schema is built, before any row is read.

Common situations: Copying a JSON-format table definition over to csv; computed column of a UDF returning RAW; internal collector schemas reusing the same DDL across formats.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/67dc0279c8639f82. Report an issue: GitHub.