prestodb/presto · error · PrestoException

ELASTICSEARCH_TYPE_MISMATCH

ELASTICSEARCH_TYPE_MISMATCH

Error message

Expected a string value for field '%s' of type VARBINARY: %s [%s]

What it means

VarbinaryDecoder.decode decodes Presto VARBINARY fields from Elasticsearch by base64-decoding a String document value. If the stored value is not a String (e.g. a number, boolean, or object), the decoder throws ELASTICSEARCH_TYPE_MISMATCH because it cannot interpret it as binary data.

Source

Thrown at presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/VarbinaryDecoder.java:50

    private final String path;

    public VarbinaryDecoder(String path)
    {
        this.path = requireNonNull(path, "path is null");
    }

    @Override
    public void decode(Hit hit, Supplier<Object> getter, BlockBuilder output)
    {
        Object value = getter.get();
        if (value == null) {
            output.appendNull();
        }
        else if (value instanceof String) {
            VARBINARY.writeSlice(output, Slices.wrappedBuffer(Base64.getDecoder().decode(value.toString())));
        }
        else {
            throw new PrestoException(ELASTICSEARCH_TYPE_MISMATCH, format("Expected a string value for field '%s' of type VARBINARY: %s [%s]", path, value, value.getClass().getSimpleName()));
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure producers base64-encode binary data before writing to Elasticsearch
  2. Fix the offending documents to contain base64-encoded strings
  3. Remap the column and convert in SQL if the data has a usable textual representation

Example fix

// before (producer)
doc.put("blob", bytes);
// after (producer)
doc.put("blob", Base64.getEncoder().encodeToString(bytes));
Defensive patterns

Strategy: validation

Validate before calling

// Confirm all values for the VARBINARY field are strings (base64)
// GET index/_search {"query":{"bool":{"must":[{"exists":{"field":"blob"}},{"bool":{"must_not":[{"term":{"blob.type-check":"string"}}]}}]}}}

Type guard

boolean isBase64String(Object v) {
  if (!(v instanceof String)) return false;
  return java.util.regex.Pattern.matches("^[A-Za-z0-9+/=\\r\\n]+$", (String) v);
}

Try / catch

try { rows = readVarbinaryColumn(); }
catch (PrestoException e) {
  if (e.getCode() == ELASTICSEARCH_TYPE_MISMATCH_CODE) {
    // reindex offending documents as base64 strings
  } else throw e;
}

Prevention

When it happens

Trigger: A VARBINARY-mapped Elasticsearch field contains a non-string JSON value in a document (e.g. a number or nested object); hit during row decoding of that document.

Common situations: Documents written without base64 encoding (raw bytes stored as numbers/arrays); dynamic mapping inferred different types across documents; a producer change switched the field from base64 string to something else.

Related errors


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