prestodb/presto · error · PrestoException

INVALID_CAST_ARGUMENT

INVALID_CAST_ARGUMENT

Error message

Cannot cast value to IPADDRESS: 

What it means

After confirming the value is a string, IpAddressDecoder.castToIpAddress tries to parse it with Guava's InetAddresses.forString. If the string is not a valid IPv4/IPv6 literal, the resulting IllegalArgumentException is rethrown as INVALID_CAST_ARGUMENT. It is a data-quality error: the value has the right JSON type but wrong content.

Source

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

        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;
            bytes[11] = (byte) 0xff;
            arraycopy(address, 0, bytes, 12, 4);
        }
        else if (address.length == 16) {
            bytes = address;
        }
        else {
            throw new PrestoException(GENERIC_INTERNAL_ERROR, "Invalid InetAddress length: " + address.length);
        }

        return wrappedBuffer(bytes);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Clean the source documents: replace invalid IP strings with valid literals or null before querying.
  2. Map the field as VARCHAR instead of IPADDRESS and filter/validate in SQL before casting.
  3. Fix the ingest pipeline to validate IPs (e.g. only emit values passing InetAddress.getByName/InetAddresses.isInetAddress).

Example fix

// before
{"src_ip": "unknown"}
// after
{"src_ip": null}  // or a valid literal like "10.0.0.5"
Defensive patterns

Strategy: validation

Validate before calling

import com.google.common.net.InetAddresses;
boolean valid = InetAddresses.isInetAddress(rawValue); // run before relying on the IP column

Type guard

function isValidIpLiteral(s) { return typeof s === 'string' && /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/.test(s) || /^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$/.test(s); }

Try / catch

try { SELECT CAST(src_ip AS IPADDRESS) FROM raw_view } catch (PrestoException e) { if (e.getErrorCode().getName().equals("INVALID_CAST_ARGUMENT")) { return null; } throw e; }

Prevention

When it happens

Trigger: A document field mapped as IPADDRESS contains a malformed string such as "999.1.1.1", "example.com", "", or an address with an invalid IPv6 zone, which fails InetAddresses.forString.

Common situations: Log shippers write hostname or placeholder values ("unknown", "-") into IP fields; truncated or corrupted IPs; IPv6 with scope-id like fe80::1%eth0 which Guava rejects.

Related errors


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