apache/cassandra · error · InvalidRequestException

More than one restriction was found for the end bound on %s

Error message

More than one restriction was found for the end bound on %s

What it means

The end-bound counterpart of error 3206: two restrictions both supply an upper bound (LT, LTE or BETWEEN) for the same clustering slice. Only one end bound is allowed, so MergedRestriction.validate() rejects the statement.

Source

Thrown at src/java/org/apache/cassandra/cql3/restrictions/MergedRestriction.java:169

            {
                ColumnMetadata column = firstColumn.position() > otherFirstColumn.position() ? firstColumn
                                                                                             : otherFirstColumn;

                throw invalidRequest("Column \"%s\" cannot be restricted by two inequalities not starting with the same column",
                                     column.name);
            }

            if ((restriction.operator() == Operator.GT || restriction.operator() == Operator.GTE || restriction.operator() == Operator.BETWEEN) &&
                    (other.operator() == Operator.GT || other.operator() == Operator.GTE || other.operator() == Operator.BETWEEN))
            {
                throw invalidRequest("More than one restriction was found for the start bound on %s",
                                     toCQLString(getColumnsInCommons(restriction, other)));
            }

            if ((restriction.operator() == Operator.LT || restriction.operator() == Operator.LTE || restriction.operator() == Operator.BETWEEN) &&
                    (other.operator() == Operator.LT || other.operator() == Operator.LTE || other.operator() == Operator.BETWEEN))
            {
                throw invalidRequest("More than one restriction was found for the end bound on %s",
                                     toCQLString(getColumnsInCommons(restriction, other)));
            }
        }
    }

    private static void checkOperator(SimpleRestriction restriction)
    {
        if (restriction.isColumnLevel() || restriction.isOnToken())
        {
            if (restriction.isEQ())
                throw invalidRequest("%s cannot be restricted by more than one relation if it includes an Equal",
                                      toCQLString(restriction.columns()));

            if (restriction.isIN())
                throw invalidRequest("%s cannot be restricted by more than one relation if it includes a IN",
                                     toCQLString(restriction.columns()));
            if (restriction.isANN())
                throw invalidRequest("%s cannot be restricted by more than one relation in an ANN ordering",

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Keep only the tighter (or desired) upper-bound restriction
  2. Rewrite as a single tuple restriction like (c1, c2) < (...)
  3. Deduplicate range predicates in any code that assembles CQL dynamically

Example fix

// before
SELECT * FROM t WHERE c1 <= 10 AND (c1, c2) <= (9, 9);
// after
SELECT * FROM t WHERE (c1, c2) <= (9, 9);
Defensive patterns

Strategy: validation

Validate before calling

const upper = predicates.filter(p => ['<','<='].includes(p.op));
if (upper.length > 1) throw new Error('Duplicate end bound on ' + upper.map(p => p.column));

Prevention

When it happens

Trigger: A SELECT with two upper-bound restrictions, e.g. WHERE c1 < 10 AND (c1, c2) <= (10, 5), or two LT/LTE/BETWEEN relations sharing columns.

Common situations: Same as start-bound duplicates: mixing single-column and multi-column range syntax; ORM query builders emitting both a BETWEEN and an explicit < predicate.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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