prestodb/presto · error · PrestoException

ELASTICSEARCH_TYPE_MISMATCH

ELASTICSEARCH_TYPE_MISMATCH

Error message

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

What it means

IpAddressDecoder expects the mapped IP field in the Elasticsearch document to be a JSON string; any other type (number, boolean, object, array) triggers this ELASTICSEARCH_TYPE_MISMATCH. The connector casts the string to Presto IPADDRESS only when the raw value is a String.

Source

Thrown at presto-elasticsearch/src/main/java/com/facebook/presto/elasticsearch/decoders/IpAddressDecoder.java:59

    {
        this.path = requireNonNull(path, "path is null");
        this.ipAddressType = requireNonNull(type, "type 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) {
            String address = (String) value;
            Slice slice = castToIpAddress(Slices.utf8Slice(address));
            ipAddressType.writeSlice(output, slice);
        }
        else {
            throw new PrestoException(ELASTICSEARCH_TYPE_MISMATCH, format("Expected a string value for field '%s' of type IP: %s [%s]", path, value, value.getClass().getSimpleName()));
        }
    }

    // This is a copy of IpAddressOperators.castFromVarcharToIpAddress method
    private Slice castToIpAddress(Slice slice)
    {
        byte[] address;
        try {
            address = InetAddresses.forString(slice.toStringUtf8()).getAddress();
        }
        catch (IllegalArgumentException e) {
            throw new PrestoException(INVALID_CAST_ARGUMENT, "Cannot cast value to IPADDRESS: " + slice.toStringUtf8());
        }

        byte[] bytes;
        if (address.length == 4) {
            bytes = new byte[16];
            bytes[10] = (byte) 0xff;

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Store the IP as a string ("192.168.1.1") in the documents, or reindex converting numeric IPs to strings.
  2. Change the Presto column mapping to BIGINT/JSON to match the stored representation and convert in SQL (e.g. with a UDF/cast).
  3. Fix the ingest pipeline to serialize IPs with InetAddress.getHostAddress().

Example fix

// before
{"client_ip": 3232235777}
// after
{"client_ip": "192.168.1.1"}
Defensive patterns

Strategy: validation

Validate before calling

SELECT t.client_ip FROM idx t WHERE t.client_ip IS NOT NULL AND TYPEOF(t.client_ip) <> 'varchar' LIMIT 1;

Type guard

function isIpString(v) { return typeof v === 'string' && /^(\d{1,3}\.){3}\d{1,3}$|^([0-9a-fA-F:]+)$/.test(v); }

Try / catch

try { SELECT client_ip FROM "idx" } catch (PrestoException e) { if (e.getErrorCode().getName().equals("ELASTICSEARCH_TYPE_MISMATCH")) { /* map column as VARCHAR and cast in SQL */ } throw e; }

Prevention

When it happens

Trigger: decode() receives a non-String value for a field mapped as Presto IPADDRESS, e.g. {"client_ip": 3232235777} (numeric form) or an object/array value.

Common situations: Documents store IPs as integers or packed binary instead of dotted-quad strings; mapping changed over time so old documents hold numeric IPs; a pipeline wrote the IP inside an object.

Related errors


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