hibernate/hibernate-orm · error · SQLException
could not reset reader
Error message
could not reset reader
What it means
In BlobProxy.resetIfNeeded(), InputStream.reset() itself threw an IOException (stream closed, or read past the mark limit — the mark is set with limit = length+1 bytes) and is rethrown as SQLException('could not reset reader'). Unlike 'Underlying stream does not allow reset', here the stream claims reset support but the reset failed at runtime.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/BlobProxy.java:107
resetIfNeeded();
return binaryStream;
}
private void resetIfNeeded() throws SQLException {
try {
if ( needsReset ) {
final InputStream inputStream = binaryStream.getInputStream();
if ( !resetAllowed && inputStream != null) {
throw new SQLException( "Underlying stream does not allow reset" );
}
if ( inputStream != null ) {
inputStream.reset();
setStreamMark();
}
}
}
catch ( IOException ioe) {
throw new SQLException("could not reset reader");
}
needsReset = true;
}
/**
* Generates a BlobImpl using byte data.
*
* @param bytes The data to be created as a Blob.
*
* @return The BlobProxy instance to represent this data.
*/
public static Blob generateProxy(byte[] bytes) {
return new BlobProxy( bytes );
}
/**
* Generates a BlobImpl proxy using a given number of bytes from an InputStream.
*View on GitHub (pinned to fad1729dce)
Solutions
- Pass the exact byte length when creating the Blob (or avoid the length-based API and use byte[])
- Materialize the content in memory (byte[]) if the Blob may be read more than once
- Ensure nothing closes or fully drains the underlying stream before Hibernate finishes with it
Example fix
// before: wrong length invalidates the mark Blob b = lobHelper.createBlob(in, guessedLength /* too small */); // after: exact length or full materialization Blob b = lobHelper.createBlob(in, in.available()); // when exact // better: byte[] bytes = in.readAllBytes(); Blob b = lobHelper.createBlob(bytes);
Defensive patterns
Strategy: validation
Validate before calling
// pass the exact length so the internal mark limit is correct long len = countExactBytes(source); // do not guess Blob b = lobHelper.createBlob(new BufferedInputStream(source), len);
Prevention
- Give accurate lengths to createBlob(stream, length)
- Do not let other code close or drain the underlying stream
- Materialize byte[] for values that may be read more than once
When it happens
Trigger: A stream-backed Blob whose underlying stream is read beyond its declared length (mark of length+1 bytes invalidated), closed between accesses, or otherwise invalidated — then accessed a second time, triggering the rewind.
Common situations: Passing an inaccurate length to createBlob(stream, length) so the mark buffer is too small; another component closing the underlying stream before flush; large streams wrapped with small fixed buffers.
Related errors
- IOException occurred reading a binary value
- Underlying stream does not allow reset
- Unable to access blob stream
- IOException occurred reading a binary value
- IOException occurred reading text
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/dd4955630054e817.
Report an issue: GitHub.