{"record":{"id":"03baa6eb576c45b1","repo":"apache/cassandra","slug":"unable-to-hardlink-from-s-to-s","errorCode":null,"errorMessage":"Unable to hardlink from %s to %s","messagePattern":"Unable to hardlink from (.+?) to (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/util/FileUtils.java","lineNumber":170,"sourceCode":"    }\n\n    public static void createHardLinkWithConfirm(File from, File to)\n    {\n        try\n        {\n            createHardLink(from, to);\n        }\n        catch (FSWriteError ex)\n        {\n            throw ex;\n        }\n        catch (DuplicateHardlinkException ex)\n        {\n            throw new RuntimeException(ex.getMessage());\n        }\n        catch (Throwable t)\n        {\n            throw new RuntimeException(String.format(\"Unable to hardlink from %s to %s\", from, to), t);\n        }\n    }\n\n    public static void createHardLinkWithoutConfirm(String from, String to)\n    {\n        createHardLinkWithoutConfirm(new File(from), new File(to));\n    }\n\n    public static void createHardLinkWithoutConfirm(File from, File to)\n    {\n        try\n        {\n            createHardLink(from, to);\n        }\n        catch (FSWriteError fse)\n        {\n            if (logger.isTraceEnabled())\n                logger.trace(\"Could not hardlink file {} to {}\", from, to, fse);","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/FileUtils.java#L152-L188","documentation":"createHardLinkWithConfirm throws this RuntimeException (with cause attached) when the underlying hardlink operation fails with any unexpected Throwable other than the handled FSWriteError/duplicate cases. It wraps low-level filesystem failures (permissions, cross-device link, full disk, missing source) into a uniform message naming both paths.","triggerScenarios":"Any failure inside Files.createLink during createHardLinkWithConfirm other than FSWriteError/DuplicateHardlinkException — e.g. destination on a different filesystem, read-only directory, or the source vanishing mid-operation.","commonSituations":"Commitlog archive directory on a different volume than the commitlog directory; insufficient permissions on the archive directory; disk full; source segment deleted concurrently by cleanup.","solutions":["Read the wrapped cause (getCause()) to identify the real filesystem error.","Place the archive directory on the same filesystem as the commitlog.","Fix permissions or free disk space on the destination directory."],"exampleFix":"// before\nFileUtils.createHardLinkWithConfirm(segment, archivePath); // opaque failure\n\n// after\nFile dest = new File(archivePath);\nif (!dest.getParentFile().canWrite())\n    throw new IllegalStateException(\"Archive dir not writable: \" + dest.getParent());\nFileUtils.createHardLinkWithConfirm(segment, archivePath);","handlingStrategy":"try-catch","validationCode":"if (!new File(to).getParentFile().canWrite()) throw new IllegalStateException(\"archive dir not writable\");","typeGuard":null,"tryCatchPattern":"try { FileUtils.createHardLinkWithConfirm(from, to); } catch (RuntimeException e) { Throwable cause = e.getCause(); /* handle FS error: permissions, disk full, cross-device */ }","preventionTips":["Keep archive and commitlog directories on the same filesystem.","Monitor disk space and directory permissions.","Always inspect getCause() — this API wraps the real filesystem error."],"tags":["io","hardlink","filesystem"],"backgroundTag":"file-write-failed","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"}