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

  1. Pad the string to even length with a leading '0': from_hex(lpad(h, LENGTH(h) + LENGTH(h) % 2, '0')).
  2. Fix the source data so the hex string has an even number of digits.
  3. Verify with LENGTH(h) % 2 = 0 before calling from_hex.
  4. 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

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


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