apache/cassandra · error · RuntimeException

Insufficient permissions on directory <path>

Error message

Insufficient permissions on directory <path>

What it means

Before listing sstables for import, SSTableImporter calls Directories.verifyFullPermissions on each source directory. If the permissions are insufficient (not readable/writable/executable by the Cassandra user) it throws a RuntimeException. The importer must be able to read the sstables and interact with transaction log files, so weak permissions are rejected up front.

Source

Thrown at src/java/org/apache/cassandra/db/SSTableImporter.java:329

     *
     * If srcPaths is empty, we create a lister that lists sstables in the data directories (deprecated use)
     */
    private List<Pair<Directories.SSTableLister, String>> getSSTableListers(Set<String> srcPaths)
    {
        List<Pair<Directories.SSTableLister, String>> listers = new ArrayList<>();

        if (!srcPaths.isEmpty())
        {
            for (String path : srcPaths)
            {
                File dir = new File(path);
                if (!dir.exists())
                {
                    throw new RuntimeException(String.format("Directory %s does not exist", path));
                }
                if (!Directories.verifyFullPermissions(dir, path))
                {
                    throw new RuntimeException("Insufficient permissions on directory " + path);
                }
                listers.add(Pair.create(cfs.getDirectories().sstableLister(dir, Directories.OnTxnErr.IGNORE).skipTemporary(true), path));
            }
        }
        else
        {
            listers.add(Pair.create(cfs.getDirectories().sstableLister(Directories.OnTxnErr.IGNORE).skipTemporary(true), null));
        }

        return listers;
    }

    private static class MovedSSTable
    {
        private final Descriptor newDescriptor;
        private final Descriptor oldDescriptor;
        private final Set<Component> components;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. chown the directory and its contents to the user running Cassandra (usually cassandra:cassandra): `chown -R cassandra:cassandra <path>`
  2. Grant full permissions for the Cassandra user: `chmod -R u+rwx <path>`
  3. Verify with `sudo -u cassandra ls -la <path>` that the service user can read and traverse the directory
  4. Check SELinux/AppArmor denials in audit logs if permissions look correct

Example fix

// before (shell)
-rw------- root root /staging/sstables-00001.db
// after
chown -R cassandra:cassandra /staging && chmod -R u+rwX /staging
Defensive patterns

Strategy: validation

Validate before calling

File dir = new File(path);
if (!dir.canRead() || !dir.canWrite() || !dir.canExecute())
    throw new IllegalStateException("Insufficient permissions for cassandra user on: " + path);

Type guard

boolean isFullyAccessible(String p) { File d = new File(p); return d.isDirectory() && d.canRead() && d.canWrite() && d.canExecute(); }

Try / catch

try { importer.importNewSSTables(...); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().startsWith("Insufficient permissions")) { /* chown/chmod and retry */ } else throw e; }

Prevention

When it happens

Trigger: Importing sstables from a directory owned by root or another user, or with restrictive mode bits (e.g. 0700 owned by another account), when running as the cassandra service user.

Common situations: Files copied into place with sudo/scp as root; backup restores where permissions were not preserved; sstables streamed from another cluster with different uid; SELinux/AppArmor restrictions.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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