alibaba/canal · warning · CanalClientException
Failed to fetch the data after: ${timeout}
Error message
Failed to fetch the data after: ${timeout} What it means
Thrown by CanalRabbitMQConsumer.getMessage when messageBlockingQueue.poll(timeout, unit) is interrupted (InterruptedException) while waiting for a batch. It is not a broker error — it means the consumer thread was signaled to stop (interrupt()) while blocked waiting for messages to arrive.
Source
Thrown at connector/rabbitmq-connector/src/main/java/com/alibaba/otter/canal/connector/rabbitmq/consumer/CanalRabbitMQConsumer.java:176
boolean isSuccess = batchMessage.isSuccess();
return isCompleted && isSuccess;
}
@Override
public List<CommonMessage> getMessage(Long timeout, TimeUnit unit) {
try {
if (this.lastGetBatchMessage != null) {
throw new CanalClientException("mq get/ack not support concurrent & async ack");
}
ConsumerBatchMessage<CommonMessage> batchMessage = messageBlockingQueue.poll(timeout, unit);
if (batchMessage != null) {
this.lastGetBatchMessage = batchMessage;
return batchMessage.getData();
}
} catch (InterruptedException ex) {
logger.warn("Get message timeout", ex);
throw new CanalClientException("Failed to fetch the data after: " + timeout);
}
return null;
}
@Override
public void rollback() {
try {
if (this.lastGetBatchMessage != null) {
this.lastGetBatchMessage.fail();
}
} finally {
this.lastGetBatchMessage = null;
}
}
@Override
public void ack() {
try {View on GitHub (pinned to 87be50e876)
Solutions
- If during shutdown, treat it as expected: log and exit cleanly, restoring the interrupt status with Thread.currentThread().interrupt().
- If unexpected, find the caller invoking interrupt() on the consumer thread and avoid interrupting it mid-poll.
- Increase the poll timeout if you want fewer wake-ups, but the interrupt itself is an external signal, not a timeout of the broker.
Example fix
// before
} catch (InterruptedException ex) {
logger.warn("Get message timeout", ex);
throw new CanalClientException("Failed to fetch the data after: " + timeout);
}
// after — distinguish interruption from a real timeout
} catch (InterruptedException ex) {
logger.warn("Get message interrupted", ex);
Thread.currentThread().interrupt(); // restore flag
throw new CanalClientException("Get message interrupted after: " + timeout);
} Defensive patterns
Strategy: try-catch
Try / catch
} catch (InterruptedException ex) {
logger.warn("Get message interrupted", ex);
Thread.currentThread().interrupt();
// during shutdown: return empty; otherwise rethrow
if (isShuttingDown()) return Collections.emptyList();
throw new CanalClientException("Get message interrupted after: " + timeout);
} Prevention
- Restore the interrupt flag after catching InterruptedException.
- Treat interruption during shutdown as expected, not an error.
- Do not interrupt the consumer thread mid-poll for non-shutdown reasons.
When it happens
Trigger: poll(timeout, unit) at line 171 throws InterruptedException because Thread.interrupt() was invoked on the consuming thread — typical during application shutdown or executor shutdownNow().
Common situations: Container/scheduler shutting down the consumer thread; explicit thread.interrupt() during stop; Spring/executor shutdownNow() interrupting blocked tasks. The message is benign if it occurs during a controlled shutdown.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Failed to fetch the data after: {}
- error
- mq get/ack not support concurrent & async ack
- Receive pulsar batch message error
- Start RabbitMQ producer error
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/21c29edc21e1e12c.
Report an issue: GitHub.