{"record":{"id":"6735bc9396e87b4e","repo":"apache/shardingsphere","slug":"decode-binlog-event-failed-errorcode-d-sqlstat","errorCode":null,"errorMessage":"Decode binlog event failed, errorCode: %d, sqlState: %s, errorMessage: %s","messagePattern":"Decode binlog event failed, errorCode: (.+?), sqlState: (.+?), errorMessage: (.+?)","errorType":"exception","errorClass":"PipelineInternalException","httpStatus":null,"severity":"critical","filePath":"kernel/data-pipeline/dialect/mysql/src/main/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/netty/MySQLBinlogEventPacketDecoder.java","lineNumber":102,"sourceCode":"                skipChecksum(binlogEventHeader.getEventType(), in);\n                return;\n            }\n            if (decodeWithTX) {\n                processEventWithTX(binlogEvent.get(), out);\n            } else {\n                processEventIgnoreTX(binlogEvent.get(), out);\n            }\n            skipChecksum(binlogEventHeader.getEventType(), in);\n        }\n    }\n    \n    private void checkPayload(final MySQLPacketPayload payload) {\n        int statusCode = payload.readInt1();\n        if (255 == statusCode) {\n            int errorNo = payload.readInt2();\n            payload.skipReserved(1);\n            String sqlState = payload.readStringFix(5);\n            throw new PipelineInternalException(\"Decode binlog event failed, errorCode: %d, sqlState: %s, errorMessage: %s\", errorNo, sqlState, payload.readStringEOF());\n        }\n        if (0 != statusCode) {\n            log.debug(\"Illegal binlog status code {}, remaining packet \\n{}\", statusCode, readRemainPacket(payload));\n        }\n    }\n    \n    private String readRemainPacket(final MySQLPacketPayload payload) {\n        return ByteBufUtil.hexDump(payload.readStringFixByBytes(payload.getByteBuf().readableBytes()));\n    }\n    \n    private boolean checkEventIntegrity(final ByteBuf in, final MySQLBinlogEventHeader binlogEventHeader) {\n        if (in.readableBytes() < binlogEventHeader.getEventSize() - MySQLBinlogEventHeader.MYSQL_BINLOG_EVENT_HEADER_LENGTH) {\n            log.debug(\"the event body is not complete, event size={}, readable bytes={}\", binlogEventHeader.getEventSize(), in.readableBytes());\n            in.resetReaderIndex();\n            return false;\n        }\n        return true;\n    }","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/kernel/data-pipeline/dialect/mysql/src/main/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/netty/MySQLBinlogEventPacketDecoder.java#L84-L120","documentation":"During MySQL incremental ingestion, MySQLBinlogEventPacketDecoder.checkPayload reads the status header of each replicated packet; a leading 0xFF byte marks a MySQL ERR packet, and the decoder throws PipelineInternalException carrying the server's error number, SQL state, and message. In other words: the MySQL server itself rejected the binlog dump stream and the pipeline surfaced it verbatim.","triggerScenarios":"Starting or running binlog replication where the server responds with an error packet: missing REPLICATION SLAVE/CLIENT privilege, binlog file/position no longer available (purged), binlog not enabled, or the account is blocked from connecting a replica stream.","commonSituations":"Pipeline/migration job user lacks REPLICATION privileges; specified binlog position/GTID purged by expire_logs_days; binlog_format=STATEMENT where ROW is required; MySQL restarted with different binlog settings mid-job.","solutions":["Read errorCode/sqlState/errorMessage from the exception — e.g. 1227/1236 map to privilege and binlog-availability problems — and fix that server-side condition.","Grant REPLICATION SLAVE, REPLICATION CLIENT (and SELECT for the dump) to the pipeline user and restart the incremental task.","Ensure log-bin is enabled with binlog_format=ROW and that the requested position/GTID still exists (SHOW BINARY LOGS); re-anchor the job if purged.","If the error is transient (restart), restart the pipeline job to re-request the stream from the recorded position."],"exampleFix":"-- before: user lacks privileges\nGRANT SELECT ON db.* TO 'pipeline'@'%';\n\n-- after\nGRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'pipeline'@'%';","handlingStrategy":"validation","validationCode":"// preflight replication readiness on MySQL source\ntry (Statement st = sourceConnection.createStatement()) {\n    ResultSet rs = st.executeQuery(\"SHOW VARIABLES LIKE 'log_bin'\"); // must be ON\n    ResultSet rs2 = st.executeQuery(\"SHOW MASTER STATUS\");       // binlog exists\n    ResultSet rs3 = st.executeQuery(\"SHOW GRANTS FOR CURRENT_USER()\"); // must include REPLICATION SLAVE\n}","typeGuard":null,"tryCatchPattern":"try {\n    channel.connect(); // binlog stream\n} catch (final PipelineInternalException ex) {\n    if (ex.getMessage().contains(\"Decode binlog event failed\")) {\n        // parse errorCode; 1236 -> purged binlog/privileges: re-anchor position or fix grants, then restart job\n    }\n}","preventionTips":["Grant REPLICATION SLAVE/CLIENT to the pipeline user before creating migration jobs.","Set binlog_format=ROW and verify with SHOW VARIABLES before starting incremental ingest.","Size binlog retention (expire_logs_days / binlog_expire_logs_seconds) larger than the longest expected job pause so positions are never purged."],"tags":["pipeline","mysql","binlog","replication","incremental"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}