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

  1. Check the descriptionEvent (FormatDescriptionLogEvent) for correct post-header lengths for the EXECTYPE_LOAD_QUERY event type.
  2. Verify the MySQL server version matches the expected post-header layout.
  3. Log the values: fnPosStart, fnPosEnd, dupHandling, and query.length() to identify which constraint is violated.
  4. 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

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


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