apache/cassandra · error · RuntimeException

You can not store Async-Profiler results into system…

Error message

You can not store Async-Profiler results into system Cassandra directory.

What it means

maybeCreateProfilesLogDir refuses to place the Async-Profiler log directory inside protected Cassandra system directories (commit log, accord journal, hints, CDC log, saved caches). Writing profiler output there could corrupt or contaminate critical operational data, so a RuntimeException is thrown when the configured log dir resolves under one of those locations.

Solutions

  1. Move the profiler log directory to a dedicated path outside all Cassandra system directories (e.g. /var/log/cassandra/async-profiler)
  2. Check the resolved dir against commitlog/hints/CDC/saved-caches/accord-journal locations in cassandra.yaml before starting
  3. Use the default log dir rather than overriding it onto a system path

Example fix

// before
async_profiler_dir: /var/lib/cassandra/commitlog/prof
// after
async_profiler_dir: /var/log/cassandra/async-profiler
Defensive patterns

Strategy: validation

Validate before calling

String dir = Path.of(profilerLogDir).toAbsolutePath().toString();
List<String> forbidden = List.of(DatabaseDescriptor.getCommitLogLocation(), DatabaseDescriptor.getHintsDirectory().absolutePath(), DatabaseDescriptor.getCDCLogLocation(), DatabaseDescriptor.getSavedCachesLocation());
if (forbidden.stream().anyMatch(l -> l != null && dir.startsWith(l))) throw new IllegalArgumentException("profiler log dir must not be a Cassandra system directory");

Try / catch

try { svc.list(); } catch (RuntimeException e) { if (e.getMessage().contains("system Cassandra directory")) { log.error("reconfigure async-profiler log dir"); throw e; } throw e; }

Prevention

When it happens

Trigger: Setting the async-profiler log directory (via the relevant cassandra config/property) to a path at or under the commitlog directory, hints directory, CDC log location, accord journal directory, or saved caches location, then calling instance()/apply()/list()/fetch()/purge().

Common situations: Operators pointing 'all Cassandra dirs' to one big mount; copy-pasted cassandra.yaml where the profiler log dir equals commitlog_location; container images sharing a single volume root.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/service/AsyncProfilerService.java:433

    {
        int durationSeconds = new DurationSpec.IntSecondsBound(duration).toSeconds();
        if (durationSeconds > MAX_SAFE_PROFILING_DURATION)
            throw new IllegalArgumentException(format("Max profiling duration is %s seconds. If you need longer profiling, use execute command instead.",
                                                      MAX_SAFE_PROFILING_DURATION));
        return durationSeconds;
    }

    private static void maybeCreateProfilesLogDir()
    {
        String dir = new File(logDir).toAbsolute().toString();

        if ((DatabaseDescriptor.getCommitLogLocation() != null && dir.startsWith(DatabaseDescriptor.getCommitLogLocation())) ||
            (DatabaseDescriptor.getAccordJournalDirectory() != null && dir.startsWith(DatabaseDescriptor.getAccordJournalDirectory())) ||
            dir.startsWith(DatabaseDescriptor.getHintsDirectory().absolutePath()) ||
            (DatabaseDescriptor.getCDCLogLocation() != null && dir.startsWith(DatabaseDescriptor.getCDCLogLocation())) ||
            (DatabaseDescriptor.getSavedCachesLocation() != null && dir.startsWith(DatabaseDescriptor.getSavedCachesLocation())))
        {
            throw new RuntimeException("You can not store Async-Profiler results into system Cassandra directory.");
        }

        for (String location : StorageService.instance.getAllDataFileLocations())
        {
            if (dir.startsWith(location))
                throw new RuntimeException("You can not store Async-Profiler results into a data directory of Cassandra.");
        }

        try
        {
            new File(logDir).createDirectoriesIfNotExists();
        }
        catch (Throwable t)
        {
            throw new RuntimeException("Unable to create directory " + logDir);
        }
    }

View on GitHub (pinned to 88fd0f6a0e)