apache/cassandra · critical · IllegalArgumentException

Unsupported pre-3.0 commit log found; cannot read.

Error message

Unsupported pre-3.0 commit log found; cannot read.

What it means

CommitLogDescriptor.readHeader reads the first int of a segment file as the version. Any version below VERSION_30 comes from a Cassandra older than 3.0, whose header layout and encodings are no longer supported, so an IllegalArgumentException is thrown. Only 3.0+ segment formats can be read.

Source

Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogDescriptor.java:157

        {
            return readHeader(raf, encryptionContext);
        }
        catch (EOFException e)
        {
            throw new RuntimeException(e);
        }
        catch (IOException e)
        {
            throw new FSReadError(e, file);
        }
    }

    public static CommitLogDescriptor readHeader(DataInput input, EncryptionContext encryptionContext) throws IOException
    {
        CRC32 checkcrc = new CRC32();
        int version = input.readInt();
        if (version < VERSION_30)
            throw new IllegalArgumentException("Unsupported pre-3.0 commit log found; cannot read.");

        updateChecksumInt(checkcrc, version);
        long id = input.readLong();
        updateChecksumInt(checkcrc, (int) (id & 0xFFFFFFFFL));
        updateChecksumInt(checkcrc, (int) (id >>> 32));
        int parametersLength = input.readShort() & 0xFFFF;
        updateChecksumInt(checkcrc, parametersLength);
        // This should always succeed as parametersLength cannot be too long even for a
        // corrupt segment file.
        byte[] parametersBytes = new byte[parametersLength];
        input.readFully(parametersBytes);
        checkcrc.update(parametersBytes, 0, parametersBytes.length);
        int crc = input.readInt();

        if (crc == (int) checkcrc.getValue())
        {
            Map<?, ?> map = (Map<?, ?>) JsonUtils.decodeJson(parametersBytes);
            return new CommitLogDescriptor(version, id, parseCompression(map), EncryptionContext.createFromMap(map, encryptionContext));

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Start the intermediate Cassandra 3.0/3.x version once to replay and flush the old commit logs, then upgrade further; never jump versions with old logs in place.
  2. Delete or move the pre-3.0 segment files out of the commitlog directory after confirming they are not needed.
  3. Restore data from snapshots/backup instead of replaying ancient commit logs.
  4. If the file is corrupt rather than genuinely old, remove it from the commitlog directory.

Example fix

// before: copying Cassandra-2.2 commitlog-*.log into a 4.x data dir -> IllegalArgumentException
// after
// 1) run Cassandra 3.0.x against the old data dir (replays logs), nodetool drain
// 2) then upgrade to 4.x
Defensive patterns

Strategy: validation

Validate before calling

int version = peekFirstInt(segmentFile);
if (version < CommitLogDescriptor.VERSION_30)
    logger.warn("{} is a pre-3.0 commit log; replay it on 3.0.x first", segmentFile);

Try / catch

try { CommitLogDescriptor.fromHeader(input, ctx); } catch (IllegalArgumentException e) { logger.error("Old/incompatible segment: {}", e.getMessage()); /* remove or upgrade first */ }

Prevention

When it happens

Trigger: readHeader (via CommitLogDescriptor.fromHeader) opening a commit log segment whose stored version int is < VERSION_30 — i.e. a segment file written by Cassandra 2.x or older, or a corrupted/garbage file whose first bytes parse as a small integer.

Common situations: Upgrading an old node without first replaying/flushing pre-3.0 commit logs, restoring an ancient backup of commitlogs, or pointing Cassandra at a directory containing unrelated or truncated files.

Related errors


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