{"record":{"id":"3f007dc010c1b58d","repo":"apache/cassandra","slug":"file-s-already-exists-can-t-move-the-file-there","errorCode":null,"errorMessage":"File %s already exists, can't move the file there","messagePattern":"File (.+?) already exists, can't move the file there","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java","lineNumber":1885,"sourceCode":"    {\n        if (!oldDescriptor.isCompatible())\n            throw new RuntimeException(String.format(\"Can't open incompatible SSTable! Current version %s, found file: %s\",\n                                                     oldDescriptor.getFormat().getLatestVersion(),\n                                                     oldDescriptor));\n\n        boolean isLive = cfs.getLiveSSTables().stream().anyMatch(r -> r.descriptor.equals(newDescriptor)\n                                                                      || r.descriptor.equals(oldDescriptor));\n        if (isLive)\n        {\n            String message = String.format(\"Can't move and open a file that is already in use in the table %s -> %s\", oldDescriptor, newDescriptor);\n            logger.error(message);\n            throw new RuntimeException(message);\n        }\n        if (newDescriptor.fileFor(Components.DATA).exists())\n        {\n            String msg = String.format(\"File %s already exists, can't move the file there\", newDescriptor.fileFor(Components.DATA));\n            logger.error(msg);\n            throw new RuntimeException(msg);\n        }\n\n        if (copyData)\n        {\n            try\n            {\n                logger.info(\"Hardlinking new SSTable {} to {}\", oldDescriptor, newDescriptor);\n                hardlink(oldDescriptor, newDescriptor, components);\n            }\n            catch (FSWriteError ex)\n            {\n                logger.warn(\"Unable to hardlink new SSTable {} to {}, falling back to copying\", oldDescriptor, newDescriptor, ex);\n                copy(oldDescriptor, newDescriptor, components);\n            }\n        }\n        else\n        {\n            logger.info(\"Moving new SSTable {} to {}\", oldDescriptor, newDescriptor);","sourceCodeStart":1867,"sourceCodeEnd":1903,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java#L1867-L1903","documentation":"moveAndOpenSSTable() verifies that the target DATA file does not already exist before moving components. If newDescriptor's -Data.db file is already present, moving would overwrite existing data, so it logs and throws a RuntimeException naming the existing file.","triggerScenarios":"Calling moveAndOpenSSTable where a file with the exact new descriptor (generation/UUID) already exists in the destination directory — e.g. re-importing the same SSTable set, or a partially completed previous move that left the data file behind.","commonSituations":"Retried sstable import jobs after a failed run; restoring backups into a directory that already contains the SSTables; concurrent imports generating the same target generation.","solutions":["Delete or rename the pre-existing target file if it is a stale leftover from a failed move","Skip SSTables whose target descriptor already exists (idempotent import logic)","Use unique generation/UUIDs for new descriptors so retries never collide","Check the destination directory before running imports (ls the data dir for conflicting xx-Data.db files)"],"exampleFix":"// before: blindly moving over possibly existing files\nFiles.move(oldData, newData);\n// after: guard against existing target\nif (Files.exists(newData)) {\n    Files.delete(newData); // or skip\n}\nFiles.move(oldData, newData);","handlingStrategy":"validation","validationCode":"// pre-check the target\nif (newDesc.fileFor(Components.DATA).exists()) {\n    // stale leftover or duplicate: delete or skip\n}","typeGuard":null,"tryCatchPattern":"try { SSTableReader.moveAndOpenSSTable(cfs, oldDesc, newDesc, comps, false); }\ncatch (RuntimeException e) {\n    if (e.getMessage().contains(\"already exists, can't move the file there\")) {\n        logger.warn(\"Target exists, cleaning stale file {}\", newDesc.fileFor(Components.DATA));\n        // delete stale file and retry once\n    } else throw e;\n}","preventionTips":["Clean up partial moves from failed runs before retrying imports","Use unique generation numbers for new descriptors","List destination directories for conflicting -Data.db files before import","Run one import job at a time per table"],"tags":["file-conflict","sstable","import"],"backgroundTag":"file-already-exists","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}