alibaba/canal · error · RuntimeException
Failed rows:{rows}
Error message
Failed rows:{rows} What it means
Thrown after the TablestoreAdapter flushes all writers and collects Future results, when one or more row writes failed (WriterResult.getFailedRows() is non-empty). The error message includes a delimited list of failure descriptions built from each RowChangeStatus. This indicates that the Table Store (OTS) write API rejected specific rows, not that the flush mechanism itself failed.
Source
Thrown at client-adapter/tablestore/src/main/java/com/alibaba/otter/canal/client/adapter/tablestore/TablestoreAdapter.java:155
for (Future<WriterResult> future : futureList) {
try {
WriterResult result = future.get();
List<WriterResult.RowChangeStatus> failedRows = result.getFailedRows();
if (!CollectionUtils.isEmpty(failedRows)) {
totalFailedRows.addAll(failedRows);
}
} catch (InterruptedException e) {
logger.info("InterruptedException", e);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
if (!CollectionUtils.isEmpty(totalFailedRows)) {
// 认为有失败的请求
List<String> msgs = totalFailedRows.stream().map(e -> buildErrorMsgForFailedRowChange(e)).collect(Collectors.toList());
throw new RuntimeException("Failed rows:" + org.springframework.util.StringUtils.collectionToDelimitedString(msgs, ",", "[", "]"));
}
} catch (Exception e) {
throw e;
}
}
/**
* 组装失败记录的信息
* @param rowChangeStatus
* @return
*/
public static String buildErrorMsgForFailedRowChange(WriterResult.RowChangeStatus rowChangeStatus) {
StringBuilder sb = new StringBuilder("{Exception:");
sb.append(rowChangeStatus.getException().getMessage()).append(",Table:")
.append(rowChangeStatus.getRowChange().getTableName()).append(",PrimaryKey:")
.append("{").append(rowChangeStatus.getRowChange().getPrimaryKey().toString())
.append("}}");View on GitHub (pinned to 87be50e876)
Solutions
- Inspect the error message details for each failed row — they typically contain the OTS error code (e.g. OTSQuotaExhausted, OTSParameterInvalid, OTSRowOperationConflict).
- If throttled, increase the OTS table's provisioned read/write capacity or enable auto-scaling.
- If PK conflicts, verify source data uniqueness and the PK mapping configuration.
- If data type mismatch, align the OTS table column types with the tablestore fieldType mapping in the config.
- For transient errors, implement retry logic or a dead-letter queue for failed rows.
Example fix
// increase OTS table throughput if throttled
// via Alibaba Cloud console or CLI:
// ots update-table --instance <name> --read-capacity 5000 --write-capacity 5000
// also check mapping config fieldType alignment
dbMapping:
targetColumns:
pk_col:
type: INTEGER Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
// Retry with backoff for transient OTS write failures
int maxRetries = 3;
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
tablestoreAdapter.sync(dmls);
break;
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Failed rows:") && attempt < maxRetries) {
logger.warn("OTS write failed on attempt {}/{}, retrying...", attempt, maxRetries);
Thread.sleep(attempt * 2000L);
continue;
}
throw e;
}
} Prevention
- Provision OTS table throughput with headroom above peak binlog event rate.
- Monitor OTS throttling metrics and set alerts before capacity is exhausted.
- Implement a dead-letter mechanism to persist failed rows for later replay.
- Validate data types between source and OTS table schema before enabling sync.
When it happens
Trigger: Calling the sync/flush path where one or more async writes to Alibaba Tablestore (OTS) returned errors — common causes include primary key conflicts (duplicate PK), throughput exceeded (throttling), data type mismatches, row size limits exceeded, or transient network issues between canal and the OTS endpoint.
Common situations: OTS table provisioned throughput is too low for the binlog event rate; duplicate PK values from source data; column data types in OTS don't match the mapping; network latency or intermittent connectivity to the OTS endpoint; large rows exceeding OTS row size limits.
Related errors
- No tablestore adapter found for config key: {key}
- count is not supportted in tablestore
- not allow to change outAdapterKey
- ERROR Config: {fileName} {errorMessage}
- dbMapping.database
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/4db5d36a8a80d833.
Report an issue: GitHub.