apache/cassandra · error · IllegalArgumentException

Route index is only allowed for accord journal table; given

Error message

Route index is only allowed for accord journal table; given %s

What it means

RouteJournalIndex.validateTargets throws this IllegalArgumentException when a route index is created on a table whose keyspace is not the Accord system keyspace (accord). Route indexes only make sense for the Accord distributed transaction journal, so Cassandra rejects them anywhere else. The keyspace check fires before the table-name and column checks.

Source

Thrown at src/java/org/apache/cassandra/index/accord/RouteJournalIndex.java:150

        Tracker tracker = baseCfs.getTracker();
        tracker.subscribe(this);
    }

    public static boolean allowed(JournalKey id)
    {
        return id.type == JournalKey.Type.COMMAND_DIFF && allowed(id.id);
    }

    public static boolean allowed(TxnId id)
    {
        return id.is(Range);
    }

    private static void validateTargets(ColumnFamilyStore baseCfs, IndexMetadata indexMetadata)
    {
        // this contains 2 columns....
        if (!SchemaConstants.ACCORD_KEYSPACE_NAME.equals(baseCfs.getKeyspaceName()))
            throw new IllegalArgumentException("Route index is only allowed for accord journal table; given " + baseCfs.metadata());
        if (!AccordKeyspace.JOURNAL.equals(baseCfs.name))
            throw new IllegalArgumentException("Route index is only allowed for accord journal table; given " + baseCfs.metadata());
        Set<String> columns = Splitter.on(',').trimResults().omitEmptyStrings().splitToStream(indexMetadata.options.get("target")).collect(Collectors.toSet());
        Set<String> expected = Set.of("record", "user_version");
        if (!expected.equals(columns))
            throw new IllegalArgumentException("Route index is only allowed for accord journal table, and on the record/user_value columns; given " + baseCfs.metadata() + " and columns " + columns);
    }

    public IndexMetrics indexMetrics()
    {
        return indexMetrics;
    }

    public RegisterStatus registerStatus()
    {
        return registerStatus;
    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Create the route index only on accord.journal
  2. Remove the RouteJournalIndex definition from non-Accord tables
  3. Use a regular index type (e.g. StorageAttachedIndex) for user tables

Example fix

// before
CREATE CUSTOM INDEX route_idx ON my_keyspace.my_table (cols) USING 'org.apache.cassandra.index.accord.RouteJournalIndex';
// after
CREATE CUSTOM INDEX route_idx ON accord.journal (record, user_version) USING 'org.apache.cassandra.index.accord.RouteJournalIndex';
Defensive patterns

Strategy: validation

Validate before calling

if (!"accord".equals(cfs.getKeyspaceName())) throw new IllegalStateException("RouteJournalIndex requires accord keyspace, got " + cfs.getKeyspaceName());

Try / catch

try { validateTargets(baseCfs, indexMetadata); } catch (IllegalArgumentException e) { /* reject index creation for non-Accord tables */ }

Prevention

When it happens

Trigger: CREATE CUSTOM INDEX ... USING 'org.apache.cassandra.index.accord.RouteJournalIndex' on any table outside the 'accord' keyspace.

Common situations: Copy-pasting an index definition from the Accord journal table to a user table; scripted schema setup applying journal indexes to all tables.

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/6215d6ac2997e697. Report an issue: GitHub.