apache/cassandra · warning

failure for repair verb ; could not complete within attempts

Error message

{} {} failure for repair verb ; could not complete within {} attempts

What it means

This is a warn-level log emitted by RepairMessage.sendMessageWithRetries when a repair message could not be delivered/replied to within the configured retry attempts due to a failure (as opposed to a timeout). It reports the failure reason and the number of attempts exhausted, and increments RepairMetrics.retryFailure for the verb.

Solutions

  1. Check the referenced node's logs and connectivity (nodetool status, ping) and restart the repair once the node is healthy
  2. Increase repair message retry settings (repair message timeout/retry configuration) if failures are transient
  3. Upgrade the peer node to a version supporting repair message retries (>= SUPPORTS_RETRY version) so failures are handled with retry/timeout semantics
  4. Tune backoff/attempt counts in the messaging retry backoff configuration

Example fix

// before
ctx.messaging().sendWithRetries(backoff, ...); // small backoff, node transiently down
// after
// fix node connectivity first, then retry repair
nodetool repair -- myks mytable; // after confirming 'nodetool status' shows the peer UL/UN
Defensive patterns

Strategy: retry

Validate before calling

// before repair
// verify all endpoints are alive and reachable
for (InetAddressAndPort ep : endpoints)
    if (!FailureDetector.instance.isAlive(ep))
        throw new IllegalStateException("Endpoint down before repair send: " + ep);

Try / catch

// retries are internal; surface exhaustion
try {
    sendMessageWithRetries(...);
} catch (RepairException | RuntimeException e) {
    logger.error("Repair verb {} failed after retries", verb, e);
    RepairMetrics.retryFailure(verb);
}

Prevention

When it happens

Trigger: Calling sendMessageWithRetries for a repair verb where the messaging layer's sendWithRetries exhausts all retry attempts with a non-timeout failure (e.g. node down, connection dropped, response failure) at the configured backoff limit.

Common situations: Repairing a cluster with an unreachable or restarting node; network partitions during repair; a target endpoint failing to respond to repair messages; messaging-layer failures (TLS handshake, dropped connections) consuming all retries.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/repair/messages/RepairMessage.java:198

            throw new AssertionError("Repair verb " + verb + " does not support retry, but a request to send with retry was given!");
        BiConsumer<Integer, RequestFailureReason > maybeRecordRetry = (attempt, reason) -> {
            if (attempt <= 1)
                return;
            // we don't know what the prefix kind is... so use NONE... this impacts logPrefix as it will cause us to use "repair" rather than "preview repair" which may not be correct... but close enough...
            String prefix = PreviewKind.NONE.logPrefix(request.parentRepairSession());
            RepairMetrics.retry(verb, attempt);
            if (reason == null)
            {
                noSpam.info("{} Retry of repair verb " + verb + " was successful after {} attempts", prefix, attempt);
            }
            else if (reason == RequestFailureReason.TIMEOUT)
            {
                noSpam.warn("{} Timeout for repair verb " + verb + "; could not complete within {} attempts", prefix, attempt);
                RepairMetrics.retryTimeout(verb);
            }
            else
            {
                noSpam.warn("{} {} failure for repair verb " + verb + "; could not complete within {} attempts", prefix, reason, attempt);
                RepairMetrics.retryFailure(verb);
            }
        };
        ctx.messaging().sendWithRetries(backoff, ctx.optionalTasks()::schedule,
                                        verb, request, Iterators.cycle(endpoint),
                                        (int attempt, Message<T> msg, Throwable failure) -> {
                                            if (failure == null)
                                            {
                                                maybeRecordRetry.accept(attempt, null);
                                                finalCallback.onResponse(msg);
                                            }
                                        },
                                        (attempt, from, failure) -> {
                                            ErrorHandling allowed = errorHandlingSupported(ctx, endpoint, verb, request.parentRepairSession());
                                            switch (allowed)
                                            {
                                                case NONE:
                                                    logger.error("[#{}] {} failed on {}: {}", request.parentRepairSession(), verb, from, failure);

View on GitHub (pinned to 88fd0f6a0e)