alibaba/canal · error · IllegalArgumentException
skipping path
Error message
skipping path
What it means
Thrown during the first pass of JSON diff parsing when the packed-long path length exceeds the total diff payload length (len). After reading the operation code, the code reads a variable-length packed integer for the path length; if this path_length is greater than the overall diff size, the data is corrupt or misaligned.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/JsonDiffConversion.java:57
public static StringBuilder print_json_diff(LogBuffer buffer, long len, String columnName, int columnIndex,
String charsetName) {
return print_json_diff(buffer, len, columnName, columnIndex, Charset.forName(charsetName));
}
public static StringBuilder print_json_diff(LogBuffer buffer, long len, String columnName, int columnIndex,
Charset charset) {
int position = buffer.position();
List<String> operation_names = new ArrayList<>();
while (buffer.hasRemaining()) {
int operation_int = buffer.getUint8();
if (operation_int >= JSON_DIFF_OPERATION_COUNT) {
throw new IllegalArgumentException("reading operation type (invalid operation code)");
}
// skip path
long path_length = buffer.getPackedLong();
if (path_length > len) {
throw new IllegalArgumentException("skipping path");
}
// compute operation name
byte[] lastP = buffer.getData(buffer.position() + (int) path_length - 1, 1);
String operation_name = json_diff_operation_name(operation_int, lastP[0]);
operation_names.add(operation_name);
buffer.forward((int) path_length);
// skip value
if (operation_int != DIFF_OPERATION_REMOVE) {
long value_length = buffer.getPackedLong();
if (value_length > len) {
throw new IllegalArgumentException("skipping path");
}
buffer.forward((int) value_length);
}
View on GitHub (pinned to 87be50e876)
Solutions
- Verify the len parameter passed to print_json_diff matches the actual column value length from the row event.
- Trace buffer position from the row event header to ensure no prior column consumed incorrect byte counts.
- Hex-dump the diff payload region to inspect the packed path_length value.
- Skip the corrupt diff and re-synchronize replication from the last known-good binlog position.
Defensive patterns
Strategy: validation
Validate before calling
// The library checks path_length > len internally.
// Callers can pre-validate by ensuring the diff payload length matches the column value size.
if (len > buffer.remaining()) {
logger.warn("Diff payload length {} exceeds buffer remaining {}", len, buffer.remaining());
return;
} Try / catch
try {
JsonDiffConversion.print_json_diff(buffer, len, columnName, columnIndex, charset);
} catch (IllegalArgumentException e) {
logger.warn("JSON diff path length exceeds payload in column {}, pos={}", columnName, buffer.position(), e);
} Prevention
- Verify the len parameter passed to print_json_diff exactly matches the column value length from the row event.
- Ensure buffer position is correctly set to the start of the diff payload before calling print_json_diff.
When it happens
Trigger: Calling print_json_diff() where, after reading a valid operation code, the path_length obtained from buffer.getPackedLong() exceeds the len parameter. This means the declared path would extend beyond the diff payload boundary.
Common situations: Binlog corruption truncating the diff payload, buffer position offset from an earlier parse consuming too few or too many bytes, or a malformed JSON partial update event from a bug in the MySQL server or an intermediate proxy that modifies binlog events.
Related errors
- reading operation type (invalid operation code)
- reading json diff
- parsing json value
- status_vars_len ( ) > data_len ( )
- No such method: '{}' @ {}
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/c4bcf778df82c74b.
Report an issue: GitHub.