prestodb/presto · error · PrestoException
INVALID_FUNCTION_ARGUMENT
INVALID_FUNCTION_ARGUMENT
Error message
invalid input length
What it means
from_hex(varchar) interprets a hex string as binary data, consuming two hex characters per output byte. The function requires the input length to be even; an odd-length string cannot be split into byte pairs, so Presto throws INVALID_FUNCTION_ARGUMENT with the offending length. Note the message text is literally "invalid input length " plus the length.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/scalar/VarbinaryFunctions.java:205
{
String encoded;
if (slice.hasByteArray()) {
encoded = BaseEncoding.base16().encode(slice.byteArray(), slice.byteArrayOffset(), slice.length());
}
else {
encoded = BaseEncoding.base16().encode(slice.getBytes());
}
return Slices.utf8Slice(encoded);
}
@Description("decode hex encoded binary data")
@ScalarFunction("from_hex")
@LiteralParameters("x")
@SqlType(StandardTypes.VARBINARY)
public static Slice fromHexVarchar(@SqlType("varchar(x)") Slice slice)
{
if (slice.length() % 2 != 0) {
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "invalid input length " + slice.length());
}
byte[] result = new byte[slice.length() / 2];
for (int i = 0; i < slice.length(); i += 2) {
result[i / 2] = (byte) ((hexDigitCharToInt(slice.getByte(i)) << 4) | hexDigitCharToInt(slice.getByte(i + 1)));
}
return Slices.wrappedBuffer(result);
}
@Description("encode value as a 64-bit 2's complement big endian varbinary")
@ScalarFunction("to_big_endian_64")
@SqlType(StandardTypes.VARBINARY)
public static Slice toBigEndian64(@SqlType(StandardTypes.BIGINT) long value)
{
Slice slice = Slices.allocate(Long.BYTES);
slice.setLong(0, Long.reverseBytes(value));
return slice;
}View on GitHub (pinned to 55bb57d202)
Solutions
- Pad the string to even length with a leading '0': from_hex(lpad(h, LENGTH(h) + LENGTH(h) % 2, '0')).
- Fix the source data so the hex string has an even number of digits.
- Verify with LENGTH(h) % 2 = 0 before calling from_hex.
- If using from_hex on varbinary input, ensure the varbinary path (fromHexVarbinary) is used and the bytes are a valid hex encoding.
Example fix
// before
SELECT from_hex('ABC');
// after
SELECT from_hex(lpad('ABC', 4, '0')); -- 0ABC Defensive patterns
Strategy: validation
Validate before calling
-- reject odd-length hex before decoding SELECT CASE WHEN LENGTH(h) % 2 = 0 THEN from_hex(h) ELSE NULL END;
Type guard
boolean isEvenLengthHex(String h) {
return h != null && h.length() % 2 == 0 && h.matches("[0-9A-Fa-f]+");
} Try / catch
try { bytes = fromHex(h); } catch (PrestoException e) { if (e.getErrorCode().getName().equals("INVALID_FUNCTION_ARGUMENT")) { bytes = fromHex(lpad(h, LENGTH(h) + 1, '0')); } else { throw e; } } Prevention
- Always zero-pad hex strings from sources that strip leading zeros.
- Validate LENGTH(h) % 2 = 0 and hex-only characters before decoding.
- Strip 0x prefixes and whitespace at ingestion time.
- Keep hex values in CHAR columns of fixed even width.
When it happens
Trigger: Calling from_hex('ABC') or any hex string whose LENGTH is odd. Also triggered by data that lost a leading zero (e.g. a value serialized without zero-padding, producing 'FFF' instead of '0FFF').
Common situations: Hex values copied from tools that strip leading zeros; strings truncated by column width limits; manual concatenation of hex fragments where one fragment has odd length.
Related errors
- INVALID_TABLE_PROPERTY
- Invalid time from server:
- Expected column to be a time type but is
- Invalid timestamp from server:
- MISSING_CATALOG
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/9a65920fb04be9d4.
Report an issue: GitHub.