apache/cassandra · error · InvalidRequestException

Counters are not supported with Accord for table

Error message

Counters are not supported with Accord for table %s.%s

What it means

Counter tables are incompatible with Accord transactions and with any transactional migration state. In validateAndUpdateTransactionalMigration (AlterTableStatement.java:651), if the table is a counter table and the next transactionalMode is not 'off' or any migration-from mode is set, this InvalidRequest is thrown.

Solutions

  1. Keep transactional_mode = 'off' on counter tables
  2. Convert the counter table to a regular table (or a separate design) before adopting Accord
  3. Filter counter tables out of scripts that set transactional_mode

Example fix

// before
ALTER TABLE metrics.counters WITH transactional_mode = 'accord';
// after
ALTER TABLE metrics.gauges WITH transactional_mode = 'accord'; // non-counter table
Defensive patterns

Strategy: validation

Validate before calling

TableMetadata t = Schema.instance.getTableMetadata(ks, table); if (t.isCounter() && params.transactionalMode != TransactionalMode.off) { /* reject: Accord unsupported on counters */ }

Try / catch

try { session.execute(alterStmt); } catch (InvalidRequestException e) { if (e.getMessage().contains("Counters are not supported with Accord")) { /* keep counters on transactional_mode = off */ } else throw e; }

Prevention

When it happens

Trigger: ALTER TABLE on a counter table setting transactional_mode to any Accord-enabled value, or setting transactional_migration_from on a counter table.

Common situations: Attempting to migrate a legacy counter table to Accord-based transactions; bulk schema scripts that apply transactional_mode to every table including counters.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java:651

            TableParams paramsForValidation = attrs.asNewTableParams(keyspaceName);
            validateDefaultTimeToLive(paramsForValidation);
            validateMinimumTrainingFrequencyForDictionaryCompressor(paramsForValidation);
        }

        private TableParams validateAndUpdateTransactionalMigration(boolean isCounter, TableParams prev, TableParams next)
        {
            if (next.transactionalMode.accordIsEnabled && SchemaConstants.isSystemKeyspace(keyspaceName))
                throw ire("Cannot enable accord on system tables (%s.%s)", keyspaceName, tableName);

            boolean modeChange = prev.transactionalMode != next.transactionalMode;
            boolean wasMigrating = prev.transactionalMigrationFrom.isMigrating();
            boolean explicitlySetMigrationFrom = attrs.hasOption(Option.TRANSACTIONAL_MIGRATION_FROM);
            // set table to migrating
            TransactionalMigrationFromMode newMigrateFrom = TransactionalMigrationFromMode.fromMode(prev.transactionalMode, next.transactionalMode);

            if (isCounter && (next.transactionalMode != TransactionalMode.off || newMigrateFrom != TransactionalMigrationFromMode.none || next.transactionalMigrationFrom != TransactionalMigrationFromMode.none))
                throw ire(format(ACCORD_COUNTER_TABLES_UNSUPPORTED, keyspaceName, tableName));

            boolean forceMigrationChange = modeChange && explicitlySetMigrationFrom && next.transactionalMigrationFrom != newMigrateFrom;

            if (modeChange && next.transactionalMode.accordIsEnabled && !DatabaseDescriptor.getAccordTransactionsEnabled())
                throw ire(format("Cannot change transactional mode to %s for %s.%s with accord.enabled set to false",
                                 next.transactionalMode, keyspaceName, tableName));

            // user is manually updating migration mode, don't interfere
            if (forceMigrationChange)
            {
                logger.warn("Forcing unsafe migration change from {} to {} with transaction mode {}", prev.transactionalMigrationFrom, next.transactionalMigrationFrom, next.transactionalMode);
                return next;
            }

            if (!modeChange)
                return next;

            // if the user is trying to revert to the mode being migrated from, allow it. The migration states will be inverted when

View on GitHub (pinned to 88fd0f6a0e)