apache/cassandra · error · java.lang.IllegalArgumentException

%s exists but is not writable

Error message

%s exists but is not writable

What it means

Thrown by CQLSSTableWriter.Builder.inDirectory(File) as an IllegalArgumentException when the directory exists but the process lacks write permission to it. The writer will not be able to create SSTable data files there, so the builder fails fast at configuration time.

Source

Thrown at src/java/org/apache/cassandra/io/sstable/CQLSSTableWriter.java:458

        {
            return inDirectory(new File(directory));
        }

        /**
         * The directory where to write the sstables (mandatory option).
         * <p>
         * This is a mandatory option.
         *
         * @param directory the directory to use, which should exists and be writable.
         * @return this builder.
         * @throws IllegalArgumentException if {@code directory} doesn't exist or is not writable.
         */
        public Builder inDirectory(File directory)
        {
            if (!directory.exists())
                throw new IllegalArgumentException(directory + " doesn't exists");
            if (!directory.isWritable())
                throw new IllegalArgumentException(directory + " exists but is not writable");

            this.directory = directory;
            return this;
        }

        public Builder withType(String typeDefinition) throws SyntaxException
        {
            typeStatements.add(QueryProcessor.parseStatement(typeDefinition, CreateTypeStatement.Raw.class, "CREATE TYPE"));
            return this;
        }

        /**
         * The schema (CREATE TABLE statement) for the table for which sstable are to be created.
         * <p>
         * Please note that the provided CREATE TABLE statement <b>must</b> use a fully-qualified
         * table name, one that include the keyspace name.
         * <p>
         * This is a mandatory option.

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Chown/chmod the directory so the running user can write (e.g. chmod u+w or chown cassandra:cassandra)
  2. Point inDirectory at a directory writable by the current user
  3. Remount the volume read-write if it is mounted ro
  4. Run the process as a user with write access to the target data directory

Example fix

// before
builder.inDirectory(new File("/var/lib/cassandra/data")); // owned by cassandra, we are root-without-write? no—other user
// after
// shell: sudo chown -R $USER /var/lib/cassandra/data  (or choose a writable dir)
builder.inDirectory(new File(System.getProperty("java.io.tmpdir"), "sstables-out"));
Defensive patterns

Strategy: validation

Validate before calling

if (dir.exists() && !dir.canWrite()) throw new IllegalStateException("no write permission on " + dir);

Type guard

null

Try / catch

try { builder.inDirectory(dir); } catch (IllegalArgumentException e) { if (e.getMessage().contains("not writable")) { /* chmod/chown or pick another dir */ } throw e; }

Prevention

When it happens

Trigger: Calling inDirectory(File) pointing at a directory that exists but is not writable by the current OS user — e.g. /var/lib/cassandra when running the bulk loader as a non-cassandra user, or a read-only mounted volume.

Common situations: Running the standalone sstableloader/bulk-loader under a different user than the data directory owner; read-only container filesystems or mounts; overly restrictive umask or chmod after provisioning.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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