{"record":{"id":"fb3da1003e86dccd","repo":"apache/cassandra","slug":"attempting-to-compact-transient-sstables-with-non","errorCode":null,"errorMessage":"Attempting to compact transient sstables with non transient sstables","messagePattern":"Attempting to compact transient sstables with non transient sstables","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/compaction/CompactionTask.java","lineNumber":478,"sourceCode":"\n        if (ids.size() != 1)\n            throw new RuntimeException(String.format(\"Attempting to compact pending repair sstables with sstables from other repair, or sstables not pending repair: %s\", ids));\n\n        return ids.iterator().next();\n    }\n\n    public static boolean getIsTransient(Set<SSTableReader> sstables)\n    {\n        if (sstables.isEmpty())\n        {\n            return false;\n        }\n\n        boolean isTransient = sstables.iterator().next().isTransient();\n\n        if (!Iterables.all(sstables, sstable -> sstable.isTransient() == isTransient))\n        {\n            throw new RuntimeException(\"Attempting to compact transient sstables with non transient sstables\");\n        }\n\n        return isTransient;\n    }\n\n\n    /*\n     * Checks if we have enough disk space to execute the compaction.  Drops the largest sstable out of the Task until\n     * there's enough space (in theory) to handle the compaction.\n     *\n     * @return true if there is enough disk space to execute the complete compaction, false if some sstables are excluded.\n     */\n    protected boolean buildCompactionCandidatesForAvailableDiskSpace(final Set<SSTableReader> nonExpiredSSTables, boolean containsExpired, TimeUUID taskId)\n    {\n        if(!cfs.isCompactionDiskSpaceCheckEnabled() && compactionType == OperationType.COMPACTION)\n        {\n            logger.info(\"Compaction space check is disabled - trying to compact all sstables\");\n            return true;","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/compaction/CompactionTask.java#L460-L496","documentation":"Incremental repair creates 'transient' SSTables on transiently-repaired replicas which must never be compacted with ordinary (non-transient) SSTables, because their data lifetime and promotion semantics differ. getIsTransient() checks that every SSTable in the compaction set agrees on transient status and aborts with this RuntimeException otherwise.","triggerScenarios":"Submitting a compaction job whose SSTable set contains both transient and non-transient SSTables for the same pending repair session.","commonSituations":"Running a cluster with transient replication and mixing outputs of full vs transient repair; bugs in PendingRepairManager partitioning; manual SSTable manipulation (e.g. after moving sstables between directories) that loses transient status distinction.","solutions":["Keep transient and non-transient SSTables in separate compaction submissions; PendingRepairManager normally does this automatically","Verify transient repair configuration is consistent across the cluster (all nodes support transient replication)","Ensure SSTables produced by transient repair are not manually relocated or re-tagged","If hit during normal operation, treat as an internal invariant violation and file a bug; avoid custom compaction code that bypasses strategy partitioning"],"exampleFix":"// before\ncompactor.compact(allRepairSstables);\n// after\nMap<Boolean, List<SSTableReader>> byTransient = allRepairSstables.stream().collect(partitioningBy(SSTableReader::isTransient));\nbyTransient.values().forEach(compactor::compact);","handlingStrategy":"validation","validationCode":"boolean t = sstables.iterator().next().isTransient();\nif (!Iterables.all(sstables, s -> s.isTransient() == t)) throw new IllegalArgumentException(\"mixed transient/non-transient sstables\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Split compaction sets by isTransient() before calling compaction APIs","Keep transient replication configuration uniform cluster-wide","Avoid manually moving or rewriting sstables produced by transient repair"],"tags":["compaction","transient-replication","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}