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

  1. Delete the existing destination (FileUtils.delete) before creating the link.
  2. Use a unique destination name (e.g. include timestamp/UUID).
  3. 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

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


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)