prestodb/presto · error · ParsingException

Binary literal can only contain hexadecimal digits

Error message

Binary literal can only contain hexadecimal digits

What it means

BinaryLiteral parses X'..' binary string literals by stripping whitespace and hex-decoding the value. If, after removing whitespace, any character is not a hexadecimal digit, the constructor throws this ParsingException because the literal cannot represent bytes.

Source

Thrown at presto-parser/src/main/java/com/facebook/presto/sql/tree/BinaryLiteral.java:47

{
    // the grammar could possibly include whitespace in the value it passes to us
    private static final Pattern WHITESPACE_PATTERN = Pattern.compile("[ \\r\\n\\t]");
    private static final Pattern NOT_HEX_DIGIT_PATTERN = Pattern.compile(".*[^A-F0-9].*");

    private final Slice value;

    public BinaryLiteral(String value)
    {
        this(Optional.empty(), value);
    }

    public BinaryLiteral(Optional<NodeLocation> location, String value)
    {
        super(location);
        requireNonNull(value, "value is null");
        String hexString = WHITESPACE_PATTERN.matcher(value).replaceAll("").toUpperCase();
        if (NOT_HEX_DIGIT_PATTERN.matcher(hexString).matches()) {
            throw new ParsingException("Binary literal can only contain hexadecimal digits", location.get());
        }
        if (hexString.length() % 2 != 0) {
            throw new ParsingException("Binary literal must contain an even number of digits", location.get());
        }
        this.value = Slices.wrappedBuffer(BaseEncoding.base16().decode(hexString));
    }

    public BinaryLiteral(NodeLocation location, String value)
    {
        this(Optional.of(location), value);
    }

    /**
     * Return the valued as a hex-formatted string with upper-case characters
     */
    public String toHexString()
    {
        return BaseEncoding.base16().encode(value.getBytes());

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Ensure every character is a hex digit (0-9, A-F)
  2. Remove any '0x' prefix from the literal content
  3. Validate the string with a regex ^[0-9A-Fa-f\s]*$ before constructing

Example fix

// before
new BinaryLiteral(location, "0x1A2B"); // contains 'x'
// after
new BinaryLiteral(location, "1A2B");
Defensive patterns

Strategy: validation

Validate before calling

String hex = value.replaceAll("\\s", "").toUpperCase();
if (!hex.matches("[0-9A-F]*")) {
    throw new IllegalArgumentException("Binary literal must contain only hex digits: " + value);
}

Type guard

boolean isHexLiteral(String value) {
    return value != null && value.replaceAll("\\s", "").matches("[0-9A-Fa-f]+");
}

Try / catch

try {
    BinaryLiteral lit = new BinaryLiteral(location, value);
} catch (ParsingException e) {
    if (e.getMessage().contains("hexadecimal digits")) {
        throw new MalformedBinaryLiteralException(value, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: new BinaryLiteral(location, value) or parsing X'...' where the content includes characters other than 0-9a-fA-F, e.g. X'GG' or X'12 3Z'.

Common situations: Copy-pasted binary data containing '0x' prefix or stray characters, hand-typed hex with typos, base64 or decimal bytes mistakenly used as hex.

Related errors


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