apache/cassandra · error · RuntimeException

Unable to hardlink from %s to %s

Error message

Unable to hardlink from %s to %s

What it means

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.

Source

Thrown at src/java/org/apache/cassandra/io/util/FileUtils.java:170

    }

    public static void createHardLinkWithConfirm(File from, File to)
    {
        try
        {
            createHardLink(from, to);
        }
        catch (FSWriteError ex)
        {
            throw ex;
        }
        catch (DuplicateHardlinkException ex)
        {
            throw new RuntimeException(ex.getMessage());
        }
        catch (Throwable t)
        {
            throw new RuntimeException(String.format("Unable to hardlink from %s to %s", from, to), t);
        }
    }

    public static void createHardLinkWithoutConfirm(String from, String to)
    {
        createHardLinkWithoutConfirm(new File(from), new File(to));
    }

    public static void createHardLinkWithoutConfirm(File from, File to)
    {
        try
        {
            createHardLink(from, to);
        }
        catch (FSWriteError fse)
        {
            if (logger.isTraceEnabled())
                logger.trace("Could not hardlink file {} to {}", from, to, fse);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Read the wrapped cause (getCause()) to identify the real filesystem error.
  2. Place the archive directory on the same filesystem as the commitlog.
  3. Fix permissions or free disk space on the destination directory.

Example fix

// before
FileUtils.createHardLinkWithConfirm(segment, archivePath); // opaque failure

// after
File dest = new File(archivePath);
if (!dest.getParentFile().canWrite())
    throw new IllegalStateException("Archive dir not writable: " + dest.getParent());
FileUtils.createHardLinkWithConfirm(segment, archivePath);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!new File(to).getParentFile().canWrite()) throw new IllegalStateException("archive dir not writable");

Try / catch

try { FileUtils.createHardLinkWithConfirm(from, to); } catch (RuntimeException e) { Throwable cause = e.getCause(); /* handle FS error: permissions, disk full, cross-device */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/03baa6eb576c45b1. Report an issue: GitHub.