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
- Ensure every character is a hex digit (0-9, A-F)
- Remove any '0x' prefix from the literal content
- 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
- Strip '0x' prefixes before building X'..' literals
- Validate hex with a regex at the input boundary
- Only accept hex from trusted encoders (e.g. Guava Base16)
- Normalize case and whitespace centrally in one helper
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
- Binary literal must contain an even number of digits
- Spaces are not allowed between 'X' and the starting quote of
- INVALID_FUNCTION_ARGUMENT
- NOT_SUPPORTED
- INVALID_LITERAL
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5301acea926d63f0.
Report an issue: GitHub.