alibaba/canal · error · CanalServerException

rollback error, clientId:%s batchId:%d is not exist , please

Error message

rollback error, clientId:%s batchId:%d is not exist , please check

What it means

Thrown by CanalServerWithEmbedded.rollback(ClientIdentity, long batchId) when MetaManager.removeBatch(clientIdentity, batchId) returns null — the batchId is not registered (already acked, already rolled back, or never existed). Note the no-arg rollback path earlier in the method returns early if the client has no subscription, so this only fires for the batchId-specific rollback of a known-subscribed client.

Source

Thrown at server/src/main/java/com/alibaba/otter/canal/server/embedded/CanalServerWithEmbedded.java:480

    /**
     * 回滚到未进行 {@link #ack} 的地方,下次fetch的时候,可以从最后一个没有 {@link #ack} 的地方开始拿
     */
    @Override
    public void rollback(ClientIdentity clientIdentity, Long batchId) throws CanalServerException {
        checkStart(clientIdentity.getDestination());
        CanalInstance canalInstance = canalInstances.get(clientIdentity.getDestination());

        // 因为存在第一次链接时自动rollback的情况,所以需要忽略未订阅
        boolean hasSubscribe = canalInstance.getMetaManager().hasSubscribe(clientIdentity);
        if (!hasSubscribe) {
            return;
        }
        synchronized (canalInstance) {
            // 清除batch信息
            PositionRange<LogPosition> positionRanges = canalInstance.getMetaManager().removeBatch(clientIdentity,
                batchId);
            if (positionRanges == null) { // 说明是重复的ack/rollback
                throw new CanalServerException(String.format("rollback error, clientId:%s batchId:%d is not exist , please check",
                    clientIdentity.getClientId(),
                    batchId));
            }

            // lastRollbackPostions.put(clientIdentity,
            // positionRanges.getEnd());// 记录一下最后rollback的位置
            // TODO 后续rollback到指定的batchId位置
            canalInstance.getEventStore().rollback();// rollback
                                                     // eventStore中的状态信息
            logger.info("rollback successfully, clientId:{} batchId:{} position:{}",
                clientIdentity.getClientId(),
                batchId,
                positionRanges);
        }
    }

    public Map<String, CanalInstance> getCanalInstances() {
        return Maps.newHashMap(canalInstances);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Treat an unknown-batch rollback as idempotent — catch CanalServerException mentioning 'is not exist' and log/continue rather than retry.
  2. Guarantee rollback is invoked once per batchId and never after a successful ack of the same batch.
  3. After restart, issue a no-arg rollback to reset cursor state instead of targeting a stale batchId.
  4. Audit concurrent client threads sharing a clientId to prevent racing ack/rollback.

Example fix

// before: rollback then retry blindly
try {
    server.rollback(clientId, batchId);
} catch (CanalServerException e) {
    server.rollback(clientId, batchId);
}
// after: idempotent handling of stale batch
try {
    server.rollback(clientId, batchId);
} catch (CanalServerException e) {
    if (!e.getMessage().contains("is not exist")) throw e;
    logger.warn("batch {} no longer tracked, rollback already applied", batchId);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    server.rollback(clientId, batchId);
} catch (CanalServerException e) {
    if (e.getMessage() != null && e.getMessage().contains("is not exist")) {
        logger.warn("duplicate rollback ignored for batch {}", batchId);
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling rollback(clientIdentity, batchId) with a batchId that was already acked or already rolled back; rolling back a batchId never delivered by get(); rolling back after the batch metadata was cleared by a server restart or ZooKeeper session loss.

Common situations: Client retry logic that re-rolls back on failure (duplicate rollback); ack already happened then a late rollback arrives; client restart re-issuing rollback for a stale batchId.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/e9cc2effe78c4e5e. Report an issue: GitHub.