{"record":{"id":"b2f04aabb30b0e18","repo":"alibaba/canal","slug":"invalid-executeloadquerylogevent-fn-pos-start-d","errorCode":null,"errorMessage":"Invalid ExecuteLoadQueryLogEvent: fn_pos_start=%d, fn_pos_end=%d, dup_handling=%d","messagePattern":"Invalid ExecuteLoadQueryLogEvent: fn_pos_start=(.+?), fn_pos_end=(.+?), dup_handling=(.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/ExecuteLoadQueryLogEvent.java","lineNumber":68,"sourceCode":"    public static final int ELQ_FILE_ID_OFFSET      = QUERY_HEADER_LEN;\n    public static final int ELQ_FN_POS_START_OFFSET = ELQ_FILE_ID_OFFSET + 4;\n    public static final int ELQ_FN_POS_END_OFFSET   = ELQ_FILE_ID_OFFSET + 8;\n    public static final int ELQ_DUP_HANDLING_OFFSET = ELQ_FILE_ID_OFFSET + 12;\n\n    public ExecuteLoadQueryLogEvent(LogHeader header, LogBuffer buffer, FormatDescriptionLogEvent descriptionEvent,\n                                    boolean compatiablePercona) throws IOException{\n        super(header, buffer, descriptionEvent, compatiablePercona);\n\n        buffer.position(descriptionEvent.commonHeaderLen + ELQ_FILE_ID_OFFSET);\n\n        fileId = buffer.getUint32(); // ELQ_FILE_ID_OFFSET\n        fnPosStart = (int) buffer.getUint32(); // ELQ_FN_POS_START_OFFSET\n        fnPosEnd = (int) buffer.getUint32(); // ELQ_FN_POS_END_OFFSET\n        dupHandling = buffer.getInt8(); // ELQ_DUP_HANDLING_OFFSET\n\n        final int len = query.length();\n        if (fnPosStart > len || fnPosEnd > len || dupHandling > LOAD_DUP_REPLACE) {\n            throw new IOException(String.format(\"Invalid ExecuteLoadQueryLogEvent: fn_pos_start=%d, \"\n                                                + \"fn_pos_end=%d, dup_handling=%d\", fnPosStart, fnPosEnd, dupHandling));\n        }\n    }\n\n    public final int getFilenamePosStart() {\n        return fnPosStart;\n    }\n\n    public final int getFilenamePosEnd() {\n        return fnPosEnd;\n    }\n\n    public final String getFilename() {\n        if (query != null) return query.substring(fnPosStart, fnPosEnd).trim();\n\n        return null;\n    }\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/ExecuteLoadQueryLogEvent.java#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// This check is internal to the constructor.\n// Callers can pre-validate by checking the event buffer size against expected post-header layout.\nint expectedMin = descriptionEvent.commonHeaderLen\n    + descriptionEvent.postHeaderLen[LogEvent.EXECUTE_LOAD_QUERY_EVENT - 1];\nif (buffer.limit() < expectedMin) {\n    logger.warn(\"ExecuteLoadQuery event too short: {} < {}\", buffer.limit(), expectedMin);\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    ExecuteLoadQueryLogEvent event = new ExecuteLoadQueryLogEvent(header, buffer, descriptionEvent, query, compatiablePercona);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Invalid ExecuteLoadQueryLogEvent\")) {\n        logger.warn(\"Malformed LOAD DATA event in binlog, skipping\");\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["binlog","mysql","load-data","event-parsing","validation"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}