{"record":{"id":"bba71811e1531a7e","repo":"apache/cassandra","slug":"last-written-key-s-current-key-s-writing-int","errorCode":null,"errorMessage":"Last written key %s >= current key %s, writing into %s","messagePattern":"Last written key (.+?) >= current key (.+?), writing into (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/sstable/format/SortedTableWriter.java","lineNumber":198,"sourceCode":"        }\n        catch (IOException e)\n        {\n            throw new FSWriteError(e, getFilename());\n        }\n    }\n\n    private boolean verifyPartition(DecoratedKey key)\n    {\n        assert key != null : \"Keys must not be null\"; // empty keys ARE allowed b/c of indexed column values\n\n        if (key.getKey().remaining() > FBUtilities.MAX_UNSIGNED_SHORT)\n        {\n            logger.error(\"Key size {} exceeds maximum of {}, skipping row\", key.getKey().remaining(), FBUtilities.MAX_UNSIGNED_SHORT);\n            return false;\n        }\n\n        if (lastWrittenKey != null && lastWrittenKey.compareTo(key) >= 0)\n            throw new RuntimeException(String.format(\"Last written key %s >= current key %s, writing into %s\", lastWrittenKey, key, getFilename()));\n\n        return true;\n    }\n\n    private void startPartition(DecoratedKey key, DeletionTime partitionLevelDeletion) throws IOException\n    {\n        partitionWriter.start(key, partitionLevelDeletion);\n        metadataCollector.updatePartitionDeletion(partitionLevelDeletion);\n\n        onStartPartition(key);\n    }\n\n    private void addStaticRow(DecoratedKey key, Row row) throws IOException\n    {\n        guardCollectionSize(key, row);\n\n        partitionWriter.addStaticRow(row);\n        if (!row.isEmpty())","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/SortedTableWriter.java#L180-L216","documentation":"SortedTableWriter.verifyPartition enforces the SSTable invariant that partitions must be written in strictly increasing decorated-key order. If the key about to be appended compares <= the last written key, it throws, because BigFormat requires sorted input and would otherwise produce an unreadable/invalid SSTable.","triggerScenarios":"Calling sstableWriter.append(partition, ...) with keys not sorted by DecoratedKey — typically a compaction/scrub/rebuild iterating sources out of order, a custom streaming or bulk-loader writing unsorted partitions, or merging sources that yield keys out of order.","commonSituations":"Custom bulk load tools (sstable writer APIs) feeding unsorted data; bugs in custom compaction strategies or external stream receivers; repairing data with mismatched sort order after reading from an unordered source.","solutions":["Sort partitions by DecoratedKey before appending (DecoratedKey.compareTo, which orders by token then key bytes).","For bulk loads, feed the writer from an ordered source or use tools that sort internally (e.g. BulkLoader/CQLSSTableWriter usage guidelines).","If writing an SSTable from unsorted data, buffer and externally merge-sort by token first.","Check custom compaction/streaming code for iteration order assumptions."],"exampleFix":"// before: appending keys in arbitrary order\nfor (UnfilteredRowIterator part : unsortedPartitions)\n    writer.append(part);\n// after: sort by decorated key first\nunsortedPartitions.sort(Comparator.comparing(p ->\n    partitioner.decorateKey(StorageEngine.getPartitionKey(p))));\nfor (UnfilteredRowIterator part : unsortedPartitions)\n    writer.append(part);","handlingStrategy":"validation","validationCode":"// Java: assert incoming partitions are sorted before writing\nDecoratedKey prev = null;\nfor (UnfilteredRowIterator part : partitions) {\n    DecoratedKey k = decorateKey(part.partitionKey());\n    if (prev != null && prev.compareTo(k) >= 0)\n        throw new IllegalStateException(\"Unsorted partitions at \" + k);\n    prev = k;\n}","typeGuard":null,"tryCatchPattern":"try {\n    writer.append(partition);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Last written key\"))\n        logger.error(\"Bulk loader emitted unsorted keys — re-sort source data\", e);\n    throw e;\n}","preventionTips":["Always sort by DecoratedKey (token then bytes) before writing SSTables","Use CQLSSTableWriter/BulkLoader rather than hand-rolled writers","Unit-test custom streaming/compaction code for key order"],"tags":["sstable","writer","sort-order","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"}