alibaba/canal · warning · RuntimeException

count is not supportted in tablestore

Error message

count is not supportted in tablestore

What it means

The TablestoreAdapter unconditionally throws this from the count() method override, because Alibaba Tablestore (OTS) does not provide a native count/aggregate API. The method exists to satisfy the CanalAdapter interface contract but is intentionally unimplemented. Any caller that invokes count() on a tablestore adapter will hit this immediately.

Source

Thrown at client-adapter/tablestore/src/main/java/com/alibaba/otter/canal/client/adapter/tablestore/TablestoreAdapter.java:243

        config.setAllowDuplicatedRowInBatchRequest(true);
        config.setConcurrency(8);
        config.setWriteMode(WriteMode.PARALLEL);

        TableStoreWriter writer = new DefaultTableStoreWriter(
                properties.get(PropertyConstants.TABLESTORE_ENDPOINT),
                credentials,
                properties.get(PropertyConstants.TABLESTORE_INSTANCENAME),
                mappingConfig.getDbMapping().getTargetTable(),
                config,
                null
        );
        return writer;
    }


    @Override
    public Map<String, Object> count(String task) {
        throw new RuntimeException("count is not supportted in tablestore");
    }


    @Override
    public String getDestination(String task) {
        MappingConfig config = tablestoreMapping.get(task);
        if (config != null) {
            return config.getDestination();
        }
        return null;
    }

    @Override
    public void destroy() {
        if (tablestoreSyncService != null) {
            tablestoreSyncService.close();
        }

View on GitHub (pinned to 87be50e876)

Solutions

  1. Do not call count() on a TablestoreAdapter — it is unsupported by design.
  2. If row counting is needed, query the OTS API separately using a RangeIterator or maintain a separate counter table.
  3. Guard the caller to skip tablestore adapters when invoking count(), checking the adapter type or catching this exception.

Example fix

// before: blindly calls count on all adapters
for (CanalAdapter adapter : adapters) {
    Map<String, Object> counts = adapter.count(task);
}

// after: skip unsupported adapters
for (CanalAdapter adapter : adapters) {
    if (!(adapter instanceof TablestoreAdapter)) {
        Map<String, Object> counts = adapter.count(task);
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

null

Type guard

// Type guard: check adapter type before calling count
public static boolean supportsCount(CanalAdapter adapter) {
    return !(adapter instanceof TablestoreAdapter);
}

// Usage:
if (supportsCount(adapter)) {
    Map<String, Object> counts = adapter.count(task);
}

Try / catch

try {
    Map<String, Object> counts = adapter.count(task);
} catch (RuntimeException e) {
    if ("count is not supportted in tablestore".equals(e.getMessage())) {
        // expected for tablestore; skip
        logger.debug("count() not supported by this adapter");
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling TablestoreAdapter.count(task) from any code path — typically from a monitoring endpoint, admin tool, or test that attempts to retrieve row counts from the target tablestore table.

Common situations: A monitoring script or canal-admin dashboard calls count() on all adapters including tablestore; automated tests iterate all adapter types and call count(); custom code that assumes all adapters support counting.

Related errors


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