alibaba/canal · error · IOException
Invalid ExecuteLoadQueryLogEvent: fn_pos_start=%d, fn_pos_en
Error message
Invalid ExecuteLoadQueryLogEvent: fn_pos_start=%d, fn_pos_end=%d, dup_handling=%d
What it means
Thrown during construction of an ExecuteLoadQueryLogEvent (MySQL LOAD DATA INFILE ... with binlog) when the file name position start, file name position end, or duplicate-handling flag read from the event post-header are invalid. Specifically, fnPosStart or fnPosEnd exceed the query string length, or dupHandling exceeds LOAD_DUP_REPLACE.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/ExecuteLoadQueryLogEvent.java:68
public static final int ELQ_FILE_ID_OFFSET = QUERY_HEADER_LEN;
public static final int ELQ_FN_POS_START_OFFSET = ELQ_FILE_ID_OFFSET + 4;
public static final int ELQ_FN_POS_END_OFFSET = ELQ_FILE_ID_OFFSET + 8;
public static final int ELQ_DUP_HANDLING_OFFSET = ELQ_FILE_ID_OFFSET + 12;
public ExecuteLoadQueryLogEvent(LogHeader header, LogBuffer buffer, FormatDescriptionLogEvent descriptionEvent,
boolean compatiablePercona) throws IOException{
super(header, buffer, descriptionEvent, compatiablePercona);
buffer.position(descriptionEvent.commonHeaderLen + ELQ_FILE_ID_OFFSET);
fileId = buffer.getUint32(); // ELQ_FILE_ID_OFFSET
fnPosStart = (int) buffer.getUint32(); // ELQ_FN_POS_START_OFFSET
fnPosEnd = (int) buffer.getUint32(); // ELQ_FN_POS_END_OFFSET
dupHandling = buffer.getInt8(); // ELQ_DUP_HANDLING_OFFSET
final int len = query.length();
if (fnPosStart > len || fnPosEnd > len || dupHandling > LOAD_DUP_REPLACE) {
throw new IOException(String.format("Invalid ExecuteLoadQueryLogEvent: fn_pos_start=%d, "
+ "fn_pos_end=%d, dup_handling=%d", fnPosStart, fnPosEnd, dupHandling));
}
}
public final int getFilenamePosStart() {
return fnPosStart;
}
public final int getFilenamePosEnd() {
return fnPosEnd;
}
public final String getFilename() {
if (query != null) return query.substring(fnPosStart, fnPosEnd).trim();
return null;
}
View on GitHub (pinned to 87be50e876)
Solutions
- Check the descriptionEvent (FormatDescriptionLogEvent) for correct post-header lengths for the EXECTYPE_LOAD_QUERY event type.
- Verify the MySQL server version matches the expected post-header layout.
- Log the values: fnPosStart, fnPosEnd, dupHandling, and query.length() to identify which constraint is violated.
- If using a MySQL fork, ensure the compatiablePercona flag is set correctly.
Defensive patterns
Strategy: validation
Validate before calling
// This check is internal to the constructor.
// Callers can pre-validate by checking the event buffer size against expected post-header layout.
int expectedMin = descriptionEvent.commonHeaderLen
+ descriptionEvent.postHeaderLen[LogEvent.EXECUTE_LOAD_QUERY_EVENT - 1];
if (buffer.limit() < expectedMin) {
logger.warn("ExecuteLoadQuery event too short: {} < {}", buffer.limit(), expectedMin);
return;
} Try / catch
try {
ExecuteLoadQueryLogEvent event = new ExecuteLoadQueryLogEvent(header, buffer, descriptionEvent, query, compatiablePercona);
} catch (IOException e) {
if (e.getMessage().startsWith("Invalid ExecuteLoadQueryLogEvent")) {
logger.warn("Malformed LOAD DATA event in binlog, skipping");
}
throw e;
} Prevention
- Verify the FormatDescriptionLogEvent has correct postHeaderLen values for the MySQL version.
- Ensure the compatiablePercona flag is set correctly for Percona/MariaDB servers.
- Check MySQL server version compatibility for LOAD DATA INFILE binlog events.
When it happens
Trigger: Constructing ExecuteLoadQueryLogEvent from a binlog buffer. After reading fileId, fnPosStart, fnPosEnd, and dupHandling from the post-header, the code validates: fnPosStart <= query.length(), fnPosEnd <= query.length(), and dupHandling <= LOAD_DUP_REPLACE. If any check fails, this IOException is thrown.
Common situations: Corrupt LOAD DATA event in the binlog, MySQL version mismatch where the post-header layout changed (different offsets for fnPosStart/fnPosEnd/dupHandling), or a binlog produced by a MySQL fork (Percona, MariaDB) with a non-standard ExecuteLoadQuery event format.
Related errors
- status_vars_len ( ) > data_len ( )
- No such method: '{}' @ {}
- No such field: '{}' @ {}
- Unable to unwrap {} to com.mysql.jdbc.ConnectionImpl
- Get null field:{}#io
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/b2f04aabb30b0e18.
Report an issue: GitHub.