prestodb/presto · error · PrestoException

ELASTICSEARCH_TYPE_MISMATCH

ELASTICSEARCH_TYPE_MISMATCH

Error message

Expected single value for column '%s', found: %s

What it means

TimestampDecoder reads the field via hit.fields() and requires exactly one value; if the JSON array for the column has more than one element it throws ELASTICSEARCH_TYPE_MISMATCH. This happens when a multi-valued (array) timestamp is returned for a column declared as a scalar TIMESTAMP.

Source

Thrown at presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/TimestampDecoder.java:62

    public TimestampDecoder(ConnectorSession session, String path)
    {
        this.path = requireNonNull(path, "path is null");
        this.zoneId = session.getSqlFunctionProperties().isLegacyTimestamp() ?
                ZoneId.of(session.getSqlFunctionProperties().getTimeZoneKey().getId()) :
                ZoneOffset.UTC;
    }

    @Override
    public void decode(Hit hit, Supplier<Object> getter, BlockBuilder output)
    {
        Object value = getter.get();
        Map<String, JsonData> fields = hit.fields();
        JsonData documentField = fields.get(path);

        if (documentField != null) {
            int size = documentField.toJson().asJsonArray().size();
            if (size > 1) {
                throw new PrestoException(ELASTICSEARCH_TYPE_MISMATCH, format("Expected single value for column '%s', found: %s", path, size));
            }
            String valueString = documentField.toJson().asJsonArray().get(0).toString();
            value = valueString.replace("\"", "");
        }

        if (value == null) {
            output.appendNull();
            return;
        }

        LocalDateTime timestamp;
        if (value instanceof String) {
            timestamp = ISO_DATE_TIME.parse((String) value, LocalDateTime::from);
        }
        else if (value instanceof Number) {
            timestamp = LocalDateTime.ofInstant(Instant.ofEpochMilli(((Number) value).longValue()), ZULU);
        }
        else {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. De-duplicate or pick one value in the documents (reindex with a script or ingest pipeline taking the first element).
  2. Change the Presto column to ARRAY(TIMESTAMP) or ARRAY(VARCHAR) and index into it in queries.
  3. Fix the mapping (set store:false / use docvalue_fields config) or the writer so only one timestamp value is stored per field.

Example fix

// before
{"event_time": ["2024-01-01T00:00:00", "2024-06-01T00:00:00"]}
// after
{"event_time": "2024-01-01T00:00:00"}
Defensive patterns

Strategy: validation

Validate before calling

// before querying, ensure only one value per doc
GET idx/_search {"_source": ["event_time"], "script_fields": {"n": {"script": "doc['event_time'].size()"}}} // any n>1 will fail

Type guard

function isSingleTimestamp(v) { return !Array.isArray(v); }

Try / catch

try { SELECT event_time FROM "idx" } catch (PrestoException e) { if (e.getErrorCode().getName().equals("ELASTICSEARCH_TYPE_MISMATCH")) { /* map column as ARRAY or dedupe */ } throw e; }

Prevention

When it happens

Trigger: decode() finds fields.get(path) yielding a JSON array of size > 1, e.g. {"event_time": ["2024-01-01T00:00:00", "2024-06-01T00:00:00"]} for a TIMESTAMP column, with stored_fields retrieval enabled.

Common situations: The Elasticsearch mapping for the field became an array (multiple values indexed over time); Presto column declared scalar TIMESTAMP while the index holds multi-valued timestamps; a pipeline appended instead of replacing values.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/7706a5f30d0fbfb1. Report an issue: GitHub.