apache/iceberg · error · IllegalStateException
HashWriter is closed.
Error message
HashWriter is closed.
What it means
HashWriter.ensureNotClosed() throws IllegalStateException once the writer has finished hashing (after getHash() closes it). A HashWriter is single-use: after digest retrieval it cannot accept writes or produce another hash.
Solutions
- Create a new HashWriter for each hash computation
- Read the digest once and store the result instead of calling getHash() repeatedly
- Refactor code to accumulate all writes before finalizing
Example fix
// before hashWriter.write(data); byte[] h1 = hashWriter.getHash(); byte[] h2 = hashWriter.getHash(); // throws // after hashWriter.write(data); byte[] hash = hashWriter.getHash(); byte[] h1 = hash, h2 = hash;
Defensive patterns
Strategy: try-catch
Validate before calling
if (hashWriterClosed) throw new IllegalStateException("create a new HashWriter"); Try / catch
try { byte[] h = hashWriter.getHash(); } catch (IllegalStateException e) { hashWriter = new HashWriter(algorithm); /* redo */ } Prevention
- Treat HashWriter as single-use: one final getHash() call
- Cache the digest result instead of re-reading
- Create a fresh HashWriter per hash computation
When it happens
Trigger: Calling write(byte[], int, int) or getHash() after a previous getHash() call set isClosed=true.
Common situations: Reusing a cached HashWriter instance across rows or files; calling getHash() twice to read the digest incrementally; resuming an aborted write after finalization.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot call acquireLock twice for
- Cannot process unknown snapshot operation
- Dynamo catalog table
- Failed to obtain Google access token. Cannot authenticate…
- Lock is not active
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1f1b08f256e15571.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/util/HashWriter.java:75
public void close() throws IOException {
isClosed = true;
}
/**
* Calculates the final hash value. The underlying digest will be reset thus subsequent getHash()
* calls are not permitted.
*
* @return bytes of final hash value
*/
public byte[] getHash() {
ensureNotClosed();
isClosed = true;
return digest.digest();
}
private void ensureNotClosed() {
if (isClosed) {
throw new IllegalStateException("HashWriter is closed.");
}
}
}
View on GitHub (pinned to 86d9c8fc54)