hibernate/hibernate-orm · error · SQLException
Length must be great-than-or-equal to zero.
Error message
Length must be great-than-or-equal to zero.
What it means
BlobProxy.getBytes(long start, int length) rejects a negative length with this SQLException. The proxy honors the JDBC contract where a read of zero bytes is legal but a negative count is a caller bug, and it fails fast before touching the underlying stream.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/BlobProxy.java:151
*
* @return The BlobProxy instance to represent this data.
*/
public static Blob generateProxy(InputStream stream, long length) {
return new BlobProxy( stream, length );
}
@Override
public long length() throws SQLException {
return binaryStream.getLength();
}
@Override
public byte[] getBytes(final long start, final int length) throws SQLException {
if ( start < 1 ) {
throw new SQLException( "Start position 1-based; must be 1 or more." );
}
if ( length < 0 ) {
throw new SQLException( "Length must be great-than-or-equal to zero." );
}
return DataHelper.extractBytes( getStream(), start-1, length );
}
@Override
public InputStream getBinaryStream() throws SQLException {
return getStream();
}
@Override
public long position(byte[] pattern, long start) {
throw notSupported();
}
@Override
public long position(Blob pattern, long start) {
throw notSupported();
}View on GitHub (pinned to fad1729dce)
Solutions
- Pass length >= 0; use 0 when you only want to validate start
- Clamp computed lengths: int len = Math.max(0, end - start)
- Never pipe indexOf/position() return values (-1 when not found) into getBytes without checking
Example fix
// before int len = end - start; // may be negative byte[] data = blob.getBytes(1, len); // after int len = Math.max(0, end - start); byte[] data = blob.getBytes(1, len);
Defensive patterns
Strategy: validation
Validate before calling
static byte[] safeGetBytes(java.sql.Blob blob, long start, int length) throws SQLException {
if (start < 1) throw new IllegalArgumentException("start must be 1-based (>= 1)");
if (length < 0) length = 0; // negative read is a bug: read nothing
return blob.getBytes(start, length);
} Try / catch
try {
data = blob.getBytes(start, length);
} catch (SQLException e) {
if (e.getMessage() != null && e.getMessage().contains("Length must be")) {
data = blob.getBytes(start, 0); // degrade to empty read
} else {
throw e;
}
} Prevention
- Clamp computed lengths with Math.max(0, end - start) before any LOB call
- Never forward -1 sentinels from indexOf/position() as lengths
- Centralize length arithmetic in one tested helper
When it happens
Trigger: Calling blob.getBytes(1, -1) on a Hibernate-created Blob; computing length as end - start and passing it negative when end < start; a 'read remainder' helper defaulting length to -1 on error paths.
Common situations: Length arithmetic bugs such as length = endIndex - startIndex with reversed or clamped indices; sentinel values (-1) leaking from indexOf/position() results into getBytes; unit tests probing invalid input.
Related errors
- Length must be great-than-or-equal to zero.
- Length must be greater than or equal to zero
- Start position 1-based; must be 1 or more.
- Start position [<start>] cannot exceed overall CLOB length [
- Can't deal with Blobs larger than 'Integer.MAX_VALUE'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/ec5cff4835a5e068.
Report an issue: GitHub.