{"record":{"id":"5af551760b6f1b19","repo":"apache/cassandra","slug":"tried-to-create-duplicate-hard-link-from-s-to-s","errorCode":null,"errorMessage":"Tried to create duplicate hard link from %s to %s","messagePattern":"Tried to create duplicate hard link from (.+?) to (.+?)","errorType":"exception","errorClass":"DuplicateHardlinkException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/util/FileUtils.java","lineNumber":135,"sourceCode":"        return createTempFile(prefix, suffix, tempDir);\n    }\n\n    public static File createDeletableTempFile(String prefix, String suffix)\n    {\n        File f = createTempFile(prefix, suffix, getTempDir());\n        f.deleteOnExit();\n        return f;\n    }\n\n    public static void createHardLink(String from, String to)\n    {\n        createHardLink(new File(from), new File(to));\n    }\n\n    public static void createHardLink(File from, File to)\n    {\n        if (to.exists())\n            throw new DuplicateHardlinkException(\"Tried to create duplicate hard link from \" + from + \" to \" + to);\n        if (!from.exists())\n            throw new RuntimeException(\"Tried to hard link to file that does not exist \" + from);\n\n        try\n        {\n            Files.createLink(to.toPath(), from.toPath());\n        }\n        catch (IOException e)\n        {\n            throw new FSWriteError(e, to);\n        }\n    }\n\n    public static void createHardLinkWithConfirm(String from, String to)\n    {\n        createHardLinkWithConfirm(new File(from), new File(to));\n    }\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/FileUtils.java#L117-L153","documentation":"createHardLink(File, File) throws DuplicateHardlinkException when the destination link `to` already exists, refusing to overwrite an existing hard link. Hard links are created during snapshot/commitlog-segment archival; creating a second link to the same target would silently overwrite the first. Callers must delete the destination or use an alternative name first.","triggerScenarios":"Calling FileUtils.createHardLink(from, to) (File or String variant) when `to.exists()` is true — e.g. re-running snapshot hardlinking without cleaning up, or restoring a commitlog archive over existing files.","commonSituations":"Commitlog archiving with a stale archive directory; repeated snapshot restore; crash recovery re-executing partially completed hardlink operations; concurrent tasks racing to link the same destination.","solutions":["Delete the existing destination (FileUtils.delete) before creating the link.","Use a unique destination name (e.g. include timestamp/UUID).","Catch DuplicateHardlinkException and treat as already-done if the existing link is correct."],"exampleFix":"// before\nFileUtils.createHardLink(from, to);\n\n// after\nFile toFile = new File(to);\nif (toFile.exists())\n    FileUtils.delete(toFile);\nFileUtils.createHardLink(from, to);","handlingStrategy":"try-catch","validationCode":"File dest = new File(to); if (dest.exists()) FileUtils.delete(dest);","typeGuard":"boolean canHardlinkTo(File to) { return !to.exists(); }","tryCatchPattern":"try { FileUtils.createHardLink(from, to); } catch (DuplicateHardlinkException e) { /* already linked: skip or delete+retry */ }","preventionTips":["Make hardlink operations idempotent (check destination first).","Use unique destination names (timestamp/UUID) for archived links.","Clean stale archive/snapshot directories before re-running tasks."],"tags":["io","hardlink","duplicate-file"],"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"}