{"record":{"id":"6bed7b89c41309a8","repo":"prestodb/presto","slug":"elasticsearch-type-mismatch-6bed7b","errorCode":"ELASTICSEARCH_TYPE_MISMATCH","errorMessage":"Expected a string value for field '%s' of type VARBINARY: %s [%s]","messagePattern":"Expected a string value for field '(.+?)' of type VARBINARY: (.+?) \\[(.+?)\\]","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/VarbinaryDecoder.java","lineNumber":50,"sourceCode":"    private final String path;\n\n    public VarbinaryDecoder(String path)\n    {\n        this.path = requireNonNull(path, \"path is null\");\n    }\n\n    @Override\n    public void decode(Hit hit, Supplier<Object> getter, BlockBuilder output)\n    {\n        Object value = getter.get();\n        if (value == null) {\n            output.appendNull();\n        }\n        else if (value instanceof String) {\n            VARBINARY.writeSlice(output, Slices.wrappedBuffer(Base64.getDecoder().decode(value.toString())));\n        }\n        else {\n            throw new PrestoException(ELASTICSEARCH_TYPE_MISMATCH, format(\"Expected a string value for field '%s' of type VARBINARY: %s [%s]\", path, value, value.getClass().getSimpleName()));\n        }\n    }\n}\n","sourceCodeStart":32,"sourceCodeEnd":54,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/VarbinaryDecoder.java#L32-L54","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure producers base64-encode binary data before writing to Elasticsearch","Fix the offending documents to contain base64-encoded strings","Remap the column and convert in SQL if the data has a usable textual representation"],"exampleFix":"// before (producer)\ndoc.put(\"blob\", bytes);\n// after (producer)\ndoc.put(\"blob\", Base64.getEncoder().encodeToString(bytes));","handlingStrategy":"validation","validationCode":"// Confirm all values for the VARBINARY field are strings (base64)\n// GET index/_search {\"query\":{\"bool\":{\"must\":[{\"exists\":{\"field\":\"blob\"}},{\"bool\":{\"must_not\":[{\"term\":{\"blob.type-check\":\"string\"}}]}}]}}}","typeGuard":"boolean isBase64String(Object v) {\n  if (!(v instanceof String)) return false;\n  return java.util.regex.Pattern.matches(\"^[A-Za-z0-9+/=\\\\r\\\\n]+$\", (String) v);\n}","tryCatchPattern":"try { rows = readVarbinaryColumn(); }\ncatch (PrestoException e) {\n  if (e.getCode() == ELASTICSEARCH_TYPE_MISMATCH_CODE) {\n    // reindex offending documents as base64 strings\n  } else throw e;\n}","preventionTips":["Always base64-encode binary data before indexing into Elasticsearch","Add an ingest pipeline that validates/coerces the field to string","Test producers' payload types in CI against the index mapping"],"tags":["elasticsearch","type-mismatch","varbinary","base64"],"backgroundTag":"schema-type-mismatch","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}