apache/cassandra · error · ConfigurationException

local_system_data_file_directory must not be the same as the

Error message

local_system_data_file_directory must not be the same as the saved_caches_directory

What it means

DatabaseDescriptor.applySimpleConfig throws this ConfigurationException when local_system_data_file_directory equals saved_caches_directory. The validation guarantees each dedicated directory (local system data, saved caches, commitlog, hints, accord journal) has its own path so that I/O and free-space checks per volume are meaningful.

Source

Thrown at src/java/org/apache/cassandra/config/DatabaseDescriptor.java:910

            if (datadir.equals(conf.hints_directory))
                throw new ConfigurationException("hints_directory must not be the same as any data_file_directories", false);
            if (datadir.equals(conf.saved_caches_directory))
                throw new ConfigurationException("saved_caches_directory must not be the same as any data_file_directories", false);

            dataFreeBytes = saturatedSum(dataFreeBytes, tryGetSpace(datadir, FileStore::getUnallocatedSpace));
        }
        if (dataFreeBytes < 64 * ONE_GIB) // 64 GB
            logger.warn("Only {} free across all data volumes. Consider adding more capacity to your cluster or removing obsolete snapshots",
                        FBUtilities.prettyPrintMemory(dataFreeBytes));

        if (conf.local_system_data_file_directory != null)
        {
            if (conf.local_system_data_file_directory.equals(conf.commitlog_directory))
                throw new ConfigurationException("local_system_data_file_directory must not be the same as the commitlog_directory", false);
            if (conf.local_system_data_file_directory.equals(conf.accord.journal_directory))
                throw new ConfigurationException("local_system_data_file_directory must not be the same as the accord.journal_directory", false);
            if (conf.local_system_data_file_directory.equals(conf.saved_caches_directory))
                throw new ConfigurationException("local_system_data_file_directory must not be the same as the saved_caches_directory", false);
            if (conf.local_system_data_file_directory.equals(conf.hints_directory))
                throw new ConfigurationException("local_system_data_file_directory must not be the same as the hints_directory", false);

            long freeBytes = tryGetSpace(conf.local_system_data_file_directory, FileStore::getUnallocatedSpace);

            if (freeBytes < ONE_GIB)
                logger.warn("Only {} free in the system data volume. Consider adding more capacity or removing obsolete snapshots",
                            FBUtilities.prettyPrintMemory(freeBytes));
        }

        if (conf.commitlog_directory.equals(conf.accord.journal_directory))
            throw new ConfigurationException("accord.journal_directory must not be the same as the commitlog_directory", false);
        if (conf.commitlog_directory.equals(conf.hints_directory))
            throw new ConfigurationException("hints_directory must not be the same as the commitlog_directory", false);
        if (conf.commitlog_directory.equals(conf.saved_caches_directory))
            throw new ConfigurationException("saved_caches_directory must not be the same as the commitlog_directory", false);

        if (conf.accord.journal_directory.equals(conf.hints_directory))

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Change saved_caches_directory (or local_system_data_file_directory) in cassandra.yaml to a distinct path.
  2. Verify with a pre-startup script that all configured *_directory values are unique strings.
  3. If saved caches can share the local-system volume by policy, still use distinct subdirectory paths to pass validation.

Example fix

// before (cassandra.yaml)
local_system_data_file_directory: /data/cassandra
saved_caches_directory: /data/cassandra
// after
local_system_data_file_directory: /data/cassandra/local_system
saved_caches_directory: /data/cassandra/saved_caches
Defensive patterns

Strategy: validation

Validate before calling

if (cfg.local_system_data_file_directory != null && cfg.local_system_data_file_directory.equals(cfg.saved_caches_directory))
    throw new IllegalArgumentException("local_system_data_file_directory must differ from saved_caches_directory");

Type guard

boolean dirsDistinct(String a, String b) { return a == null || b == null || !new File(a).getAbsolutePath().equals(new File(b).getAbsolutePath()); }

Try / catch

try { DatabaseDescriptor.applyAll(cfg); } catch (ConfigurationException e) { logger.error("Directory collision: {}", e.getMessage()); System.exit(1); }

Prevention

When it happens

Trigger: Set cassandra.yaml local_system_data_file_directory to the same path as saved_caches_directory and start the node; config is validated during toolInitialization/applyAll before any other startup work.

Common situations: Shared defaults in generated cassandra.yaml templates; Docker images where all data directories are flattened to a single volume path; operators who set only one custom path variable and reused it for multiple directory keys.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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