tursodatabase/turso · error · SQLException
Error reading Unicode stream
Error message
Error reading Unicode stream
What it means
setUnicodeStream(int, InputStream, int) reads up to length bytes and decodes them as UTF-8; any IOException from the stream during the copy is wrapped in this SQLException. As with the ASCII variant, the statement never executes — the failure is in reading the caller's stream at bind time.
Source
Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4PreparedStatement.java:224
}
if (length < 0) {
throw new SQLException("setUnicodeStream length must be non-negative");
}
if (length == 0) {
setParam(parameterIndex, "");
return;
}
try {
byte[] buffer = new byte[length];
int offset = 0;
int read;
while (offset < length && (read = x.read(buffer, offset, length - offset)) > 0) {
offset += read;
}
String text = new String(buffer, 0, offset, StandardCharsets.UTF_8);
setParam(parameterIndex, text);
} catch (IOException e) {
throw new SQLException("Error reading Unicode stream", e);
}
}
@Override
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
requireNonNull(this.statement);
if (x == null) {
setParam(parameterIndex, null);
return;
}
if (length < 0) {
throw new SQLException("setBinaryStream length must be non-negative");
}
if (length == 0) {
setParam(parameterIndex, new byte[0]);
return;
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {View on GitHub (pinned to bad083fafb)
Solutions
- Inspect SQLException.getCause() for the real IOException and fix the source (keep it alive, add retries).
- Open and bind the stream within one try-with-resources scope.
- Migrate off the deprecated setUnicodeStream to setCharacterStream with an InputStreamReader(UTF-8) while you are fixing the lifecycle.
Example fix
// before
ps.setUnicodeStream(1, in, len); // in was closed elsewhere
// after
try (Reader r = new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8)) {
ps.setCharacterStream(1, r, len);
} Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast if the stream is already closed
try {
in.available();
} catch (IOException closed) {
throw new IllegalStateException("stream closed before binding", closed);
} Try / catch
try {
ps.setUnicodeStream(1, in, len);
} catch (SQLException e) {
if (e.getCause() instanceof IOException ioe) {
// stream failure — reopen source or fail with context; also plan migration to setCharacterStream
}
throw e;
} Prevention
- Bind streams in the same scope where you open them.
- Buffer untrusted sources to memory before binding.
- Replace deprecated setUnicodeStream calls while touching this code.
When it happens
Trigger: Already-closed InputStream; file deleted or rotated after open; network-backed stream resetting during the bounded read; GZIP stream failing mid-decompression.
Common situations: File cleanup jobs racing the bind; streaming from remote object storage; a stream consumed earlier by logging or checksumming code.
Related errors
- Error reading ASCII stream
- Error reading binary stream
- Error reading character stream
- Error reading InputStream
- setAsciiStream length must be non-negative
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/16e7ce6d9cdd9ebd.
Report an issue: GitHub.