apache/cassandra · error · InvalidRequestException

Cannot DROP COMPACT STORAGE as some nodes in the cluster (%s

Error message

Cannot DROP COMPACT STORAGE as some nodes in the cluster (%s) has some non-upgraded 2.x sstables. Please run `upgradesstables` on those nodes before retrying

What it means

Cassandra refuses to drop COMPACT STORAGE when some nodes in the cluster still hold non-upgraded 2.x-format SSTables. DROPPING COMPACT STORAGE rewrites the table layout, and the schema change is only safe if every node has fully upgraded its on-disk data. The check collects the set of nodes reported via gossip/SSTable versions and rejects the ALTER TABLE if any node still has 2.x sstables.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java:819

                    {
                        // Means VersionType::fromString didn't parse a version correctly. Which shouldn't happen, we shouldn't
                        // have garbage in Gossip. But crashing the request is not ideal, so we log the error but ignore the
                        // node otherwise.
                        noSpamLogger.error("Unexpected error parsing sstable versions from gossip for {} (gossiped value " +
                                           "is '{}'). This is a bug and should be reported. Cannot ensure that {} has no " +
                                           "non-upgraded 2.x sstables anymore. If after this DROP COMPACT STORAGE some old " +
                                           "sstables cannot be read anymore, please use `upgradesstables` with the " +
                                           "`--force-compact-storage-on` option.", node, sstableVersionsString, node);
                    }
                }
            }

            if (!before4.isEmpty())
                throw new InvalidRequestException(format("Cannot DROP COMPACT STORAGE as some nodes in the cluster (%s) " +
                                                         "are not on 4.0+ yet. Please upgrade those nodes and run " +
                                                         "`upgradesstables` before retrying.", before4));
            if (!with2xSStables.isEmpty())
                throw new InvalidRequestException(format("Cannot DROP COMPACT STORAGE as some nodes in the cluster (%s) " +
                                                         "has some non-upgraded 2.x sstables. Please run `upgradesstables` " +
                                                         "on those nodes before retrying", with2xSStables));
        }
    }

    public static class AlterConstraints extends AlterTableStatement
    {
        final ColumnIdentifier columnName;
        final ColumnConstraints.Raw constraints;
        final boolean ifColumnExists;

        AlterConstraints(String keyspaceName, String tableName, boolean ifTableExists, boolean ifColumnExists, ColumnIdentifier columnName, ColumnConstraints.Raw constraints)
        {
            super(keyspaceName, tableName, ifTableExists);
            this.columnName = columnName;
            this.constraints = constraints;
            this.ifColumnExists = ifColumnExists;
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. On every node listed in the error message, run `nodetool upgradesstables` so all 2.x sstables are rewritten to the current format.
  2. Verify with `nodetool tablestats` / sstable metadata (sstable version in `find *.db` metadata or `nodetool info`) that no 2.x sstables remain.
  3. Retry the `ALTER TABLE ... DROP COMPACT STORAGE` statement once all nodes report upgraded sstables.
  4. If stale sstables are unneeded (e.g. old snapshots), remove snapshots/compact so upgradesstables can eliminate them.

Example fix

// before (fails on mixed cluster)
ALTER TABLE myks.mytable DROP COMPACT STORAGE;

// after: on each listed node first
$ nodetool upgradesstables
// then
ALTER TABLE myks.mytable DROP COMPACT STORAGE;
Defensive patterns

Strategy: validation

Validate before calling

// before running DROP COMPACT STORAGE, check per node:
// nodetool tablestats <table> | grep -i sstable   and check sstable versions via
// nodetool upgradesstables (idempotent) ; only proceed once upgrades complete
String out = exec("nodetool upgradesstables");
if (clusterHas2xSStables()) throw new IllegalStateException("run upgradesstables on all nodes first");

Try / catch

try { session.execute("ALTER TABLE ks.t DROP COMPACT STORAGE"); }
catch (com.datastax.driver.core.exceptions.InvalidQueryException e) {
  if (e.getMessage().contains("non-upgraded 2.x sstables")) scheduleUpgradesstablesOnListedNodes(e.getMessage());
  else throw e;
}

Prevention

When it happens

Trigger: Running `ALTER TABLE ... DROP COMPACT STORAGE` on a cluster where at least one node still has 2.x sstables (reported as with2xSStables), typically after a rolling upgrade where `nodetool upgradesstables` was not run on all nodes.

Common situations: Mixed-version rolling upgrades (2.x -> 3.x/4.x); nodes that were upserted with old snapshots or backups containing 2.x sstables; forgetting `nodetool upgradesstables` after upgrading; restored data directories with pre-upgrade sstables.

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/9e8a049be58904f2. Report an issue: GitHub.