apache/cassandra · error · InvalidRequestException

LIKE value can't contain a % other than at the start and/or…

Error message

LIKE value can't contain a % other than at the start and/or end

What it means

LIKE in Cassandra only supports % wildcards at the very start and/or end of the pattern (prefix, suffix, contains, or exact match). Any % appearing in the interior of the pattern after those are stripped causes this error in LikePattern.parse.

Solutions

  1. Move interior % wildcards to the start/end only, or use an exact/prefix/suffix/contains form the parser accepts
  2. Implement in-memory filtering of the remaining matches if arbitrary wildcard search is required (e.g. LIKE prefix then filter client-side)
  3. Use SASI/SAI index search capabilities if available for richer matching instead of LIKE

Example fix

// before
SELECT * FROM users WHERE name LIKE 'jo%hn';
// after
SELECT * FROM users WHERE name LIKE '%john%'; // or use a supported prefix/suffix/contains pattern
Defensive patterns

Strategy: validation

Validate before calling

function hasOnlyEdgeWildcards(p) {
  const core = p.replace(/^%/, '').replace(/%$/, '');
  return !core.includes('%');
}
if (!hasOnlyEdgeWildcards(userInput)) throw new Error('interior % not supported by Cassandra LIKE');

Type guard

function isCqlLikeSafe(p) { return typeof p === 'string' && !p.slice(1, -1).slice(p.startsWith('%') ? 1 : 0, p.endsWith('%') ? -1 : undefined).includes('%'); }

Prevention

When it happens

Trigger: Queries such as col LIKE 'a%b' or col LIKE '%a%b%' where a WILDCARD remains inside the trimmed ByteBuffer; ByteBufferUtil.contains(newValue, WILDCARD) detects the interior % and throws.

Common situations: See trigger scenarios.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/restrictions/LikePattern.java:117

            kind = Kind.SUFFIX;
            beginIndex += 1;
            endIndex += 1;
        }
        else
        {
            kind = Kind.MATCHES;
            endIndex += 1;
        }

        if (endIndex == 0 || beginIndex == endIndex)
            throw invalidRequest("LIKE value can't be empty.");

        ByteBuffer newValue = value.duplicate();
        newValue.position(beginIndex);
        newValue.limit(endIndex);
        // Checking if we still have WILDCARD in value and if yes return error.
        if (ByteBufferUtil.contains(newValue, WILDCARD))
            throw invalidRequest("LIKE value can't contain a % other than at the start and/or end");
        return new LikePattern(kind, newValue);
    }
}

View on GitHub (pinned to 88fd0f6a0e)