apache/cassandra · error · IllegalArgumentException

Snapshot name '' is reserved

Error message

Snapshot name '' is reserved

What it means

IllegalArgumentException from SnapshotOptions.validateTag: the tag reaching validation is empty, producing the literal reserved-name message. validateTag is a guard over user-supplied snapshot names; it fires when callers bypass the earlier 'must supply a name' check with a value that resolves to '' (or is path-traversal-reserved like '.'/'..'), which Cassandra reserves and never allows as a snapshot directory name.

Source

Thrown at src/java/org/apache/cassandra/service/snapshot/SnapshotOptions.java:225

            if (rateLimiter == null)
                rateLimiter = DatabaseDescriptor.getSnapshotRateLimiter();

            return new SnapshotOptions(this);
        }

        private void validateTag(String tag)
        {
            if (tag == null || tag.isEmpty())
                throw new IllegalArgumentException("You must supply a snapshot name.");

            if (tag.contains(File.pathSeparator()))
            {
                throw new IllegalArgumentException("Snapshot name cannot contain " + File.pathSeparator());
            }

            if (tag.equals(".") || tag.equals(".."))
            {
                throw new IllegalArgumentException("Snapshot name '" + tag + "' is reserved");
            }

            if (!CassandraRelevantProperties.SNAPSHOT_NAME_VALIDATION.getBoolean())
                return;

            // Pre-generate snapshot name for the sake of the validation.
            // getSnapshotName logic does not return raw "tag" as snapshot name every time,
            // it e.g. prepends timestamp and type for system snapshots, and we need to validate it as a whole.
            // If, for example, tag would be less than max allowed FILENAME_LENGTH,
            // we might in fact produce a snapshot name longer than FILENAME_LENGTH if we prepended a timestamp to it.
            String resolvedSnapshotName = SnapshotOptions.getSnapshotName(type, tag, now());

            // the length of valid snapshot name has to be less than or equal to FILENAME_LEGTH - that is 255 -
            // we are following the max length as it is in SchemaConstants for table name.
            if (resolvedSnapshotName.length() > SchemaConstants.FILENAME_LENGTH)
            {
                throw new IllegalArgumentException(format("Snapshot name must not be more than %d characters long for " +
                                                          "resolved snapshot name (got %d characters for \"%s\")",

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use a descriptive, non-reserved tag (e.g. 'snap-2024-01-01').
  2. Normalize the path first and pick a real filename component, not '.' or '..'.
  3. Add a guard in scripts: if [ "$tag" = "." ] || [ "$tag" = ".." ]; then abort; fi.
  4. Quote variables in shell scripts to avoid accidental dot-segment expansion.

Example fix

// before
String tag = new File(dir).getName(); // dir=".." -> tag=".."
takeSnapshot(tag, keyspace);
// after
String tag = "snap-" + new File(dir).getCanonicalFile().getName();
takeSnapshot(tag, keyspace);
Defensive patterns

Strategy: validation

Validate before calling

boolean isReserved(String tag) { return ".".equals(tag) || "..".equals(tag); }

Try / catch

try { takeSnapshot(tag, ks); } catch (IllegalArgumentException e) { if (e.getMessage().contains("is reserved")) { tag = "snap-" + System.currentTimeMillis(); retry(); } }

Prevention

When it happens

Trigger: Passing tag '.' or '..' (literally or produced by path-normalization logic that strips a directory component).

Common situations: Scripts that join a directory path and use its last element as the tag, ending up with '..'; hand-edited configs containing dot segments.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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