apache/cassandra · error · RuntimeException

Invalid option combination: Can not provide tokens when…

Error message

Invalid option combination: Can not provide tokens when using user-defined

What it means

Nodetool Compact rejects combining --user-defined with token-based options (--start-token/--end-token) or --partition-key; user-defined compaction takes raw SSTable file arguments only. Thrown locally before any JMX call.

Solutions

  1. Remove the token/partition-key arguments when using --user-defined.
  2. Or remove --user-defined and keep the range/partition specification.
  3. Choose one compaction strategy per invocation.

Example fix

// before
nodetool compact --user-defined --partition-key ks:tbl:key ks
// after
nodetool compact --user-defined ks tbl data-ka-1-Data.db
Defensive patterns

Strategy: validation

Validate before calling

boolean tokenProvided = !(startToken.isEmpty() && endToken.isEmpty()) || !partitionKey.isEmpty();
if (userDefined && tokenProvided)
    throw new IllegalArgumentException("--user-defined accepts only SSTable file arguments, not tokens/partition keys");

Try / catch

try { executeCompaction(...); }
catch (RuntimeException e) { if (e.getMessage().startsWith("Invalid option combination")) { printUsage(); System.exit(2); } throw e; }

Prevention

When it happens

Trigger: Passing `--user-defined` along with --start-token/--end-token or --partition-key in one `nodetool compact` invocation.

Common situations: Copy-pasting flags from two different compaction recipes; misunderstanding that user-defined selects files, not ranges.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/tools/nodetool/Compact.java:78

            names = {"-j", "--jobs"},
            description = "Use -j to specify the maximum number of threads to use for parallel compaction. " +
                          "If not set, up to half the compaction threads will be used. " +
                          "If set to 0, the major compaction will use all threads and will not permit other compactions to run until it completes (use with caution).")
    private Integer parallelism = null;

    @Override
    public void execute(NodeProbe probe)
    {
        final boolean startEndTokenProvided = !(startToken.isEmpty() && endToken.isEmpty());
        final boolean partitionKeyProvided = !partitionKey.isEmpty();
        final boolean tokenProvided = startEndTokenProvided || partitionKeyProvided;
        if (splitOutput && (userDefined || tokenProvided))
        {
            throw new RuntimeException("Invalid option combination: Can not use split-output here");
        }
        if (userDefined && tokenProvided)
        {
            throw new RuntimeException("Invalid option combination: Can not provide tokens when using user-defined");
        }

        if (userDefined)
        {
            try
            {
                String userDefinedFiles = String.join(",", args);
                probe.forceUserDefinedCompaction(userDefinedFiles);
            } catch (Exception e) {
                throw new RuntimeException("Error occurred during user defined compaction", e);
            }
            return;
        }

        List<String> keyspaces = parseOptionalKeyspace(args, probe);
        String[] tableNames = parseOptionalTables(args);

        for (String keyspace : keyspaces)

View on GitHub (pinned to 88fd0f6a0e)