apache/cassandra · error · IllegalStateException

[%s] Writer already finished!

Error message

[%s] Writer already finished!

What it means

AbstractBlockPackedWriter guards against writing to a block-packed writer after finish() has been called. Once finished, the block footer/counts are flushed to the IndexOutput, so any further add() (or a second finish()) would corrupt the written file. The exception names the underlying index output file to make the offending component identifiable.

Source

Thrown at src/java/org/apache/cassandra/index/sai/disk/v1/bitpack/AbstractBlockPackedWriter.java:122

        while ((i & ~0x7FL) != 0L && k++ < 8)
        {
            out.writeByte((byte) ((i & 0x7FL) | 0x80L));
            i >>>= 7;
        }
        out.writeByte((byte) i);
    }

    private void flush() throws IOException
    {
        flushBlock();
        blockIndex = 0;
    }

    private void checkNotFinished()
    {
        if (finished)
        {
            throw new IllegalStateException(String.format("[%s] Writer already finished!", indexOutput.getName()));
        }
    }
}

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Do not call add() after finish(); restructure the write loop so all values are added before finish().
  2. Guard call sites with a finished flag or assert !writer.isFinished() before adding.
  3. If triggered by an internal flush bug, verify against the Cassandra version and check for known SAI segment-builder fixes; upgrade.

Example fix

// before
writer.add(value);
writer.finish();
writer.add(more); // throws
// after
writer.add(value);
writer.add(more);
writer.finish();
Defensive patterns

Strategy: type-guard

Type guard

boolean canWrite(AbstractBlockPackedWriter w) { return !w.isFinished(); }

Try / catch

try { writer.add(v); } catch (IllegalStateException e) { log.error("Write after finish", e); throw e; }

Prevention

When it happens

Trigger: Calling add() after finish() on the same writer, or calling finish() twice; happens when a segment write loop keeps posting rows after the writer was closed out, e.g. double-flush in a segment builder.

Common situations: Bugs in SAI segment builders that finish writers early on empty segments or on flush/replay paths, then attempt more writes; internal Cassandra code, not user-triggered directly.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/b3d503879a00231d. Report an issue: GitHub.