{"record":{"id":"be86c498714511ca","repo":"apache/cassandra","slug":"not-yet-safe-to-use-non-durable-replaymode","errorCode":null,"errorMessage":"Not yet safe to use NON_DURABLE ReplayMode","messagePattern":"Not yet safe to use NON_DURABLE ReplayMode","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/accord/journal/Replay.java","lineNumber":65,"sourceCode":"\nimport static accord.local.RedundantStatus.Property.LOCALLY_DURABLE_TO_COMMAND_STORE;\nimport static accord.local.RedundantStatus.Property.LOCALLY_DURABLE_TO_DATA_STORE;\nimport static org.apache.cassandra.service.accord.JournalKey.Type.COMMAND_DIFF;\nimport static org.apache.cassandra.utils.FBUtilities.getAvailableProcessors;\n\npublic class Replay\n{\n    private static final Logger logger = LoggerFactory.getLogger(Replay.class);\n\n    static boolean replay(AccordJournal journal, ReplayMode replayMode, CommandStore[] commandStores, Object param)\n    {\n        AbstractReplayer.Mode accordReplayerMode;\n        switch (replayMode)\n        {\n            default: throw new UnhandledEnum(replayMode);\n            case NON_DURABLE:\n                accordReplayerMode = AbstractReplayer.Mode.NON_DURABLE;\n                throw new UnsupportedOperationException(\"Not yet safe to use NON_DURABLE ReplayMode\");\n            case PART_NON_DURABLE:\n                accordReplayerMode = AbstractReplayer.Mode.PART_NON_DURABLE;\n                break;\n            case ALL:\n            case RESET:\n                accordReplayerMode = AbstractReplayer.Mode.ALL;\n        }\n\n        Invariants.require(param == null || param.getClass() == Long2LongHashMap.class, \"Param should be null or a map of commandStoreId->minSegmentId\");\n        final Long2LongHashMap minSegments = param == null || journal.rangeSearch != null ? new Long2LongHashMap(0L) : (Long2LongHashMap) param;\n        if (journal.rangeSearch != null)\n            logger.warn(\"journal_sai index enabled, which means safe replay markers do not reduce replay work\");\n\n        // TODO (expected): make the parallelisms configurable\n        // Replay is performed in parallel, where at most X commands can be in flight, across at most Y commands stores.\n        // That is, you can limit replay parallelism to 1 command store at a time, but load multiple commands within that data store,\n        // _or_ have multiple commands being loaded accross multiple data stores.\n        final Semaphore commandParallelism = Semaphore.newSemaphore(getAvailableProcessors());","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/accord/journal/Replay.java#L47-L83","documentation":"Replay.replay maps a ReplayMode onto the internal replayer mode. The NON_DURABLE mode is explicitly unimplemented: after assigning the enum value the code unconditionally throws UnsupportedOperationException 'Not yet safe to use NON_DURABLE ReplayMode'. This is an intentional guard preventing use of a feature that is not yet safe.","triggerScenarios":"Invoking journal replay with ReplayMode.NON_DURABLE, e.g. via the internal replay/journal control path or diagnostic tooling that selects the replay mode.","commonSituations":"Developers experimenting with replay modes during Accord journal debugging; tooling or scripts that pass NON_DURABLE expecting it to work; using a branch where the feature is not yet landed.","solutions":["Use ReplayMode.PART_NON_DURABLE, ALL, or RESET instead of NON_DURABLE.","Remove NON_DURABLE from any scripts/tooling driving journal replay.","Upgrade to a Cassandra version where NON_DURABLE replay is implemented, if it becomes available."],"exampleFix":"// before\nReplay.replay(ReplayMode.NON_DURABLE, ...);\n// after\nReplay.replay(ReplayMode.PART_NON_DURABLE, ...);","handlingStrategy":"type-guard","validationCode":"if (mode == ReplayMode.NON_DURABLE) throw new IllegalArgumentException(\"NON_DURABLE replay is not implemented; use PART_NON_DURABLE/ALL/RESET\");","typeGuard":"boolean replayModeSupported(ReplayMode m) { return m != ReplayMode.NON_DURABLE; }","tryCatchPattern":"try { replay(mode); } catch (UnsupportedOperationException e) { LOG.error(\"ReplayMode rejected: {}\", e.getMessage()); }","preventionTips":["Never script NON_DURABLE replay mode.","Check supported modes in the Replay class of your version before automation.","Default tooling to PART_NON_DURABLE or ALL."],"tags":["accord","journal","unsupported-operation"],"backgroundTag":"operation-not-supported","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"}