apache/shardingsphere · error · IllegalStateException

Failed to read java.sql.Blob content

Error message

Failed to read java.sql.Blob content

What it means

Thrown while reading the contents of a java.sql.Blob parameter for the Firebird wire protocol: the binary stream was opened successfully, but reading it raised IOException (the sibling SQLException path produces 'Failed to read java.sql.Blob stream'). The original IOException is chained. Typical causes are an interrupted/closed stream or a LOB whose underlying storage vanished mid-read.

Source

Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/protocol/FirebirdBlobBinaryProtocolValue.java:107

    }
    
    @Override
    public void write(final FirebirdPacketPayload payload, final Object value) {
        long blobId;
        
        if (null == value) {
            blobId = 0L;
        } else if (value instanceof Long) {
            blobId = (Long) value;
        } else if (value instanceof byte[]) {
            blobId = register(payload.getConnectionId(), (byte[]) value);
        } else if (value instanceof Blob) {
            try {
                blobId = register(payload.getConnectionId(), readAllBytes(((Blob) value).getBinaryStream()));
            } catch (final SQLException ex) {
                throw new IllegalStateException("Failed to read java.sql.Blob stream", ex);
            } catch (final IOException ex) {
                throw new IllegalStateException("Failed to read java.sql.Blob content", ex);
            }
        } else if (value instanceof Clob) {
            try {
                Clob clob = (Clob) value;
                int len = (int) Math.min(Integer.MAX_VALUE, clob.length());
                String str = clob.getSubString(1L, len);
                blobId = register(payload.getConnectionId(), str.getBytes(payload.getCharset()));
            } catch (final SQLException ex) {
                throw new IllegalStateException("Failed to read java.sql.Clob", ex);
            }
        } else {
            blobId = register(payload.getConnectionId(), value.toString().getBytes(payload.getCharset()));
        }
        
        payload.writeInt8(blobId);
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Inspect the chained IOException for the true I/O failure (file closed, socket reset, buffer freed)
  2. If the Blob is driver-backed, keep its transaction open until after parameter binding completes
  3. Materialize the bytes up front and bind with setBytes() to eliminate the streaming path
  4. For custom Blob classes, verify getBinaryStream() returns a fully readable, open stream

Example fix

// before: streaming Blob whose source may vanish mid-read
ps.setBlob(1, maybeBrokenBlob);

// after: read eagerly while the source is still valid, then bind bytes
byte[] bytes = readAllBytes(maybeBrokenBlob.getBinaryStream()); // handle errors at your boundary
ps.setBytes(1, bytes);
Defensive patterns

Strategy: try-catch

Validate before calling

// drain the Blob stream eagerly inside your own error boundary before binding
byte[] bytes;
try (InputStream in = blob.getBinaryStream()) {
    bytes = in.readAllBytes();
} catch (IOException | SQLException ex) {
    throw new IllegalArgumentException("blob source unreadable", ex);
}
ps.setBytes(1, bytes); // no streaming path left to fail inside the protocol writer

Try / catch

try {
    ps.setBlob(1, blob);
} catch (IllegalStateException ex) {
    if (ex.getCause() instanceof IOException) {
        // underlying stream failed: retry once from the materialized copy if you kept one
        ps.setBytes(1, cachedBytes);
    } else {
        throw ex;
    }
}

Prevention

When it happens

Trigger: Passing a java.sql.Blob whose getBinaryStream() returns a stream that fails during readAllBytes() — e.g. the LOB buffer was freed, the socket to the backing store dropped, or a custom Blob implementation throws IOException from read().

Common situations: Custom Blob implementations wrapping files/network streams where the source becomes unavailable; database-side temp-LOBs invalidated by transaction end; large BLOBs whose read crosses a driver buffer timeout.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/e904d6c0f2479898. Report an issue: GitHub.