apache/cassandra · error · DuplicateHardlinkException
Tried to create duplicate hard link from
Error message
Tried to create duplicate hard link from %s to %s
What it means
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.
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.
Example fix
// before
FileUtils.createHardLink(from, to);
// after
File toFile = new File(to);
if (toFile.exists())
FileUtils.delete(toFile);
FileUtils.createHardLink(from, to); Defensive patterns
Strategy: try-catch
Validate before calling
File dest = new File(to); if (dest.exists()) FileUtils.delete(dest);
Type guard
boolean canHardlinkTo(File to) { return !to.exists(); } Try / catch
try { FileUtils.createHardLink(from, to); } catch (DuplicateHardlinkException e) { /* already linked: skip or delete+retry */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Failed to remove hard link files
- Tried to hard link to file that does not exist
- Unable to hardlink from
- Attempted skipBytes() on a closed RAR
- Attempted to seek in a closed RAR
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5af551760b6f1b19.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/io/util/FileUtils.java:135
return createTempFile(prefix, suffix, tempDir);
}
public static File createDeletableTempFile(String prefix, String suffix)
{
File f = createTempFile(prefix, suffix, getTempDir());
f.deleteOnExit();
return f;
}
public static void createHardLink(String from, String to)
{
createHardLink(new File(from), new File(to));
}
public static void createHardLink(File from, File to)
{
if (to.exists())
throw new DuplicateHardlinkException("Tried to create duplicate hard link from " + from + " to " + to);
if (!from.exists())
throw new RuntimeException("Tried to hard link to file that does not exist " + from);
try
{
Files.createLink(to.toPath(), from.toPath());
}
catch (IOException e)
{
throw new FSWriteError(e, to);
}
}
public static void createHardLinkWithConfirm(String from, String to)
{
createHardLinkWithConfirm(new File(from), new File(to));
}
View on GitHub (pinned to 88fd0f6a0e)