apache/cassandra · critical · AssertionError
Invalid custom verb id + id + - we only allow custom ids…
Error message
Invalid custom verb id + id + - we only allow custom ids between 0 and MAX_CUSTOM_VERB_ID
What it means
For CUSTOM-kind verbs, ids must fall in [0, MAX_CUSTOM_VERB_ID] so they fit in the custom id space after idForCustomVerb() offsetting. Exceeding that bound is treated as a developer error and fails with AssertionError in the Verb constructor.
Solutions
- Use a custom id between 0 and MAX_CUSTOM_VERB_ID; idForCustomVerb() computes the wire id
- Reuse an existing unused custom id slot instead of inventing a large one
- Check Verb.MAX_CUSTOM_VERB_ID/CUSTOM_VERB_START constants when adding verbs
Example fix
// before MY_VERB(CUSTOM, CUSTOM_VERB_START, ...) // after MY_VERB(CUSTOM, 1, ...) // small custom index; wire id derived via idForCustomVerb
Defensive patterns
Strategy: validation
Validate before calling
if (kind == Verb.Kind.CUSTOM && !(id >= 0 && id <= Verb.MAX_CUSTOM_VERB_ID)) throw new IllegalArgumentException("custom verb id out of range: " + id); Prevention
- Pick custom verb ids as small sequential indices in [0, MAX_CUSTOM_VERB_ID]
- Never use built-in wire ids for custom verbs
- Consult CUSTOM_VERB_START/MAX_CUSTOM_VERB_ID constants when registering verbs
When it happens
Trigger: Declaring Verb(CUSTOM, id, ...) with id > MAX_CUSTOM_VERB_ID, e.g. picking a raw wire id equal to a built-in verb's id instead of a small custom index.
Common situations: Adding custom verbs (e.g. for messaging-coordinator or test extensions) and choosing an id from the built-in range instead of the custom range.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid verb id + id + - we only allow ids between 0 and…
- Verb id must be non-negative, got + id + for verb + name()
- Unsupported type: + type
- Unsupported Verb Kind: + v.kind + for verb + v
- Addresses differ: !=
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/6bfb8c9530b0633f.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/net/Verb.java:489
{
this(NORMAL, id, priority, expiration, stage, serializer, handler, responseVerb);
}
Verb(Kind kind, int id, Priority priority, ToLongFunction<TimeUnit> expiration, Stage stage, Supplier<? extends IVersionedAsymmetricSerializer<?, ?>> serializer, Supplier<? extends IVerbHandler<?>> handler)
{
this(kind, id, priority, expiration, stage, serializer, handler, null);
}
Verb(Kind kind, int id, Priority priority, ToLongFunction<TimeUnit> expiration, Stage stage, Supplier<? extends IVersionedAsymmetricSerializer<?, ?>> serializer, Supplier<? extends IVerbHandler<?>> handler, Verb responseVerb)
{
this.stage = stage;
if (id < 0)
throw new IllegalArgumentException("Verb id must be non-negative, got " + id + " for verb " + name());
if (kind == CUSTOM)
{
if (id > MAX_CUSTOM_VERB_ID)
throw new AssertionError("Invalid custom verb id " + id + " - we only allow custom ids between 0 and " + MAX_CUSTOM_VERB_ID);
this.id = idForCustomVerb(id);
}
else
{
if (id > CUSTOM_VERB_START - MAX_CUSTOM_VERB_ID)
throw new AssertionError("Invalid verb id " + id + " - we only allow ids between 0 and " + (CUSTOM_VERB_START - MAX_CUSTOM_VERB_ID));
this.id = id;
}
this.priority = priority;
this.serializer = serializer;
this.handler = handler;
this.responseVerb = responseVerb;
this.expiration = expiration;
this.kind = kind;
// this is a little hacky, but reduces the number of parameters up top
this.isResponse = name().endsWith("_RSP") || handler == RESPONSE_HANDLER;
}
View on GitHub (pinned to 88fd0f6a0e)