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
- Clean the source documents: replace invalid IP strings with valid literals or null before querying.
- Map the field as VARCHAR instead of IPADDRESS and filter/validate in SQL before casting.
- 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
- Map IP fields as Elasticsearch 'ip' type so invalid literals are rejected at indexing time.
- Sanitize placeholder values like 'unknown' or '-' to null in the ingest pipeline.
- Query via a VARCHAR view and use TRY_CAST to isolate bad rows.
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
- ELASTICSEARCH_TYPE_MISMATCH
- ELASTICSEARCH_TYPE_MISMATCH
- ELASTICSEARCH_TYPE_MISMATCH
- ELASTICSEARCH_TYPE_MISMATCH
- ELASTICSEARCH_TYPE_MISMATCH
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b0212107fdcc1335.
Report an issue: GitHub.