alibaba/canal · error · IOException
ROW_RESULT is unsupported
Error message
ROW_RESULT is unsupported
What it means
Thrown while decoding a UserVarLogEvent whose value type is ROW_RESULT. The inline comment states 'this seems to be banned in MySQL altogether' — MySQL does not produce ROW_RESULT user variables in the binlog, so a well-formed MySQL stream never reaches this branch. Hitting it implies a non-MySQL source or a corrupted type byte.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/UserVarLogEvent.java:109
value = Double.valueOf(buffer.getDouble64()); // float8get
break;
case INT_RESULT:
if (valueLen == 8) value = Long.valueOf(buffer.getLong64()); // !uint8korr
else if (valueLen == 4) value = Long.valueOf(buffer.getUint32());
else throw new IOException("Error INT_RESULT length: " + valueLen);
break;
case DECIMAL_RESULT:
final int precision = buffer.getInt8();
final int scale = buffer.getInt8();
value = buffer.getDecimal(precision, scale); // bin2decimal
break;
case STRING_RESULT:
Charset charset = CharsetConversion.getNioCharset(charsetNumber);
value = buffer.getFixString(valueLen, charset);
break;
case ROW_RESULT:
// this seems to be banned in MySQL altogether
throw new IOException("ROW_RESULT is unsupported");
default:
value = null;
break;
}
buffer.limit(limit);
}
}
public final String getQuery() {
if (value == null) {
return "SET @" + name + " := NULL";
} else if (type == STRING_RESULT) {
// TODO: do escaping !?
return "SET @" + name + " := \'" + value + '\'';
} else {
return "SET @" + name + " := " + String.valueOf(value);
}
}View on GitHub (pinned to 87be50e876)
Solutions
- Verify the binlog source is genuine MySQL and the event is not forged.
- Inspect the event with mysqlbinlog --hexdump; if corrupt, reseed from a valid position.
- If the source legitimately emits ROW_RESULT, patch UserVarLogEvent to skip/null the value instead of throwing.
Example fix
// before
case ROW_RESULT:
throw new IOException("ROW_RESULT is unsupported");
// after: skip gracefully
case ROW_RESULT:
logger.warn("ROW_RESULT user variable encountered, setting value to null");
value = null;
break; Defensive patterns
Strategy: try-catch
Try / catch
try {
userVarEvent.parse();
} catch (IOException e) {
if (e.getMessage().equals("ROW_RESULT is unsupported")) {
logger.warn("ROW_RESULT user variable encountered; not produced by MySQL. Skipping.");
} else throw e;
} Prevention
- Confirm the binlog source is genuine MySQL (ROW_RESULT is banned upstream).
- Inspect forged/synthetic events with mysqlbinlog --hexdump.
- Patch UserVarLogEvent to null-skip ROW_RESULT if your source legitimately emits it.
When it happens
Trigger: A UserVarLogEvent carries a type byte equal to ROW_RESULT. Not produced by standard MySQL; only seen from a forged or corrupt binlog or a non-MySQL-compatible source emulating the protocol.
Common situations: Binlog corruption flipping the type byte; a third-party tool injecting synthetic binlog events; replicating from a system that is not real MySQL.
Related errors
- Error INT_RESULT length:
- Read error:
- !! Don't know how to handle column type=%d meta=%d (%04X)
- !! Unknown Bit len =
- !! Unknown ENUM packlen =
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/7c42d8f7bf0ec05a.
Report an issue: GitHub.