apache/cassandra · warning · RuntimeException

is not the latest version, run upgradesstables

Error message

%s is not the latest version, run upgradesstables

What it means

`nodetool verify` with the checkVersion option rejects SSTables whose on-disk format version is not the latest for the running Cassandra version. It throws a plain RuntimeException (deliberately not CorruptSSTableException) because the file is not corrupt, just outdated; the fix is running upgradesstables to rewrite it in the current format.

Solutions

  1. Run `nodetool upgradesstables` to rewrite SSTables to the current version.
  2. If upgradesstables skips them, run `nodetool upgradesstables --include-all-sstables`.
  3. Alternatively run `nodetool scrub` or a full compaction to rewrite the files.
  4. Drop --check-version from verify if the old format is still acceptable (it will be upgraded by normal compaction).

Example fix

// before: verify fails on old-format sstable
nodetool verify --check-version keyspace1 standard1
// after: upgrade format first, then verify
nodetool upgradesstables keyspace1 standard1
nodetool verify --check-version keyspace1 standard1
Defensive patterns

Strategy: validation

Validate before calling

// Java: check sstable version before verifying with checkVersion
boolean latest = sstable.descriptor.version.isLatestVersion();
if (!latest) System.out.println("Run upgradesstables for " + sstable.getFilename());

Prevention

When it happens

Trigger: Running `nodetool verify --check-version` (or equivalent options.invokedBy verification) against SSTables written by an older Cassandra version (e.g. pre-upgrade files, files restored from old snapshots) that haven't been upgraded.

Common situations: After a rolling Cassandra upgrade before `nodetool upgradesstables` completed; restoring old snapshots/backup files; nodes that rejoined with legacy SSTables.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/io/sstable/format/SortedTableVerifier.java:214

                !statsComponent.validationMetadata().partitioner.equals(sstable.getPartitioner().getClass().getCanonicalName()))
                throw new IOException("Partitioner does not match validation metadata");
        }
        catch (Throwable t)
        {
            outputHandler.warn(t);
            markAndThrow(t, false);
        }
    }

    protected void verifySSTableVersion()
    {
        outputHandler.output("Verifying %s (%s)", sstable, FBUtilities.prettyPrintMemory(dataFile.length()));
        if (options.checkVersion && !sstable.descriptor.version.isLatestVersion())
        {
            String msg = String.format("%s is not the latest version, run upgradesstables", sstable);
            outputHandler.output(msg);
            // don't use markAndThrow here because we don't want a CorruptSSTableException for this.
            throw new RuntimeException(msg);
        }
    }

    protected int verifyOwnedRanges()
    {
        List<Range<Token>> ownedRanges = Collections.emptyList();
        if (outputHandler.isDebugEnabled()) outputHandler.debug("Checking that all tokens are owned by the current node");
        try (KeyIterator iter = sstable.keyIterator())
        {
            ownedRanges = Range.normalize(tokenLookup.apply(cfs.metadata.keyspace));
            if (ownedRanges.isEmpty())
                return 0;
            RangeOwnHelper rangeOwnHelper = new RangeOwnHelper(ownedRanges);
            while (iter.hasNext())
            {
                DecoratedKey key = iter.next();
                rangeOwnHelper.validate(key);
            }

View on GitHub (pinned to 88fd0f6a0e)