hibernate/hibernate-orm · error · IllegalArgumentException
The string is not a valid string representation of a binary
Error message
The string is not a valid string representation of a binary content.
What it means
PrimitiveByteArrayJavaType.fromString() decodes byte[] from hexadecimal text and requires an even number of characters (two hex digits per byte). Any odd-length string - truncated hex, a stray nibble, values with partial '0x'-style prefixes - is rejected with IllegalArgumentException before parsing starts. This path is used when binary values are materialized from text, e.g. varchar columns on databases lacking a binary type.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveByteArrayJavaType.java:99
if ( hexStr.length() == 1 ) {
appender.append( '0' );
}
appender.append( hexStr );
}
}
@Override
public String extractLoggableRepresentation(byte[] value) {
return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value );
}
@Override
public byte[] fromString(CharSequence string) {
if ( string == null ) {
return null;
}
if ( string.length() % 2 != 0 ) {
throw new IllegalArgumentException( "The string is not a valid string representation of a binary content." );
}
byte[] bytes = new byte[string.length() / 2];
for ( int i = 0; i < bytes.length; i++ ) {
final String hexStr = string.subSequence( i * 2, (i + 1) * 2 ).toString();
bytes[i] = (byte) Integer.parseInt( hexStr, 16 );
}
return bytes;
}
public <X> X unwrap(byte[] value, Class<X> type, WrapperOptions options) {
if ( value == null ) {
return null;
}
if ( byte[].class.isAssignableFrom( type ) ) {
return type.cast( value );
}
if ( InputStream.class.isAssignableFrom( type ) ) {
return type.cast( new ByteArrayInputStream( value ) );View on GitHub (pinned to fad1729dce)
Solutions
- Fix the data: hex must have even length; re-export or repair truncated values
- Use a real binary column type (VARBINARY, BLOB, RAW) so no hex round-trip occurs
- Validate length % 2 == 0 (and [0-9a-fA-F] only) at every write path before persisting
- If base64 or prefixed hex is the real format, use an AttributeConverter that decodes it properly
Example fix
// before UPDATE files SET hash_hex = '0AF'; // odd length // loading byte[] attribute -> IllegalArgumentException // after UPDATE files SET hash_hex = '00AF'; // plus a write-side guard: if (hex.length() % 2 != 0) throw ...
Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidHex(byte[] target, CharSequence s) {
return s != null && s.length() % 2 == 0 && s.chars().allMatch(c -> Character.digit(c, 16) >= 0);
}
if (!isValidHex(null, text)) throw new IllegalArgumentException("Even-length hex string required: " + text); Type guard
static byte[] tryHexDecode(String s) {
if (s == null || s.length() % 2 != 0) return null;
try { return java.util.HexFormat.of().parseHex(s); } catch (Exception e) { return null; }
} Try / catch
catch (IllegalArgumentException e) {
if (e.getMessage().contains("binary content"))
throw new IllegalArgumentException("Hex text must have even length: '" + text + "'", e);
throw e;
} Prevention
- Enforce even-length, [0-9a-f] hex at every write boundary
- Use native binary columns (VARBINARY/BLOB/RAW) instead of hex text
- Add a checksum/length column to detect truncated hex imports
When it happens
Trigger: A byte[] attribute backed by a text column whose content has odd length (truncated by ETL or hand editing); hex strings with an odd nibble like '0AF'; another writer storing base64 or '0x'-prefixed hex that left a stray character
Common situations: Storing binary as hex on databases without VARBINARY/BLOB support; data cleanup jobs that trimmed characters; integrations that concatenate hex strings incorrectly
Related errors
- The string is not a valid string representation of a binary
- Unable to access lob stream
- Illegal XML content:
- No more item in JSON document
- Unexpected JsonProcessingState {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/7a86f818435d4a86.
Report an issue: GitHub.