prestodb/presto · error · ParsingException
Binary literal must contain an even number of digits
Error message
Binary literal must contain an even number of digits
What it means
A binary literal must encode whole bytes, so the hex string must have an even number of digits. BinaryLiteral checks hexString.length() % 2 and throws this ParsingException for odd-length values, since they cannot be decoded into complete bytes.
Source
Thrown at presto-parser/src/main/java/com/facebook/presto/sql/tree/BinaryLiteral.java:50
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());
}
public Slice getValue()View on GitHub (pinned to 55bb57d202)
Solutions
- Pad the hex string with a leading zero to make the length even
- Fix the data source so full bytes are emitted
- Validate value.replaceAll("\\s","").length() % 2 == 0 before constructing
Example fix
// before new BinaryLiteral(location, "ABC"); // 3 digits // after new BinaryLiteral(location, "0ABC"); // 4 digits, even
Defensive patterns
Strategy: validation
Validate before calling
String hex = value.replaceAll("\\s", "");
if (hex.length() % 2 != 0) {
hex = "0" + hex; // left-pad to a whole byte
} Type guard
boolean isEvenLengthHex(String value) {
return value != null && value.replaceAll("\\s", "").length() % 2 == 0;
} Try / catch
try {
BinaryLiteral lit = new BinaryLiteral(location, value);
} catch (ParsingException e) {
if (e.getMessage().contains("even number of digits")) {
throw new MalformedBinaryLiteralException(value, e);
}
throw e;
} Prevention
- Left-pad odd hex strings with a leading zero
- Check byte-array-to-hex encoders emit pairs (they should)
- Fix truncation points where hex dumps get sliced
- Validate length parity at the input boundary
When it happens
Trigger: Constructing BinaryLiteral with an odd-length hex string, e.g. X'ABC' or X'123'.
Common situations: Hand-truncated hex dumps, off-by-one slicing of hex strings, padding dropped by string processing.
Related errors
- Binary literal can only contain hexadecimal 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/745942dac67b1f9f.
Report an issue: GitHub.