apache/shardingsphere · critical · PipelineInternalException

Decode binlog event failed, errorCode: %d, sqlState: %s, err

Error message

Decode binlog event failed, errorCode: %d, sqlState: %s, errorMessage: %s

What it means

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.

Source

Thrown at kernel/data-pipeline/dialect/mysql/src/main/java/org/apache/shardingsphere/data/pipeline/mysql/ingest/incremental/client/netty/MySQLBinlogEventPacketDecoder.java:102

                skipChecksum(binlogEventHeader.getEventType(), in);
                return;
            }
            if (decodeWithTX) {
                processEventWithTX(binlogEvent.get(), out);
            } else {
                processEventIgnoreTX(binlogEvent.get(), out);
            }
            skipChecksum(binlogEventHeader.getEventType(), in);
        }
    }
    
    private void checkPayload(final MySQLPacketPayload payload) {
        int statusCode = payload.readInt1();
        if (255 == statusCode) {
            int errorNo = payload.readInt2();
            payload.skipReserved(1);
            String sqlState = payload.readStringFix(5);
            throw new PipelineInternalException("Decode binlog event failed, errorCode: %d, sqlState: %s, errorMessage: %s", errorNo, sqlState, payload.readStringEOF());
        }
        if (0 != statusCode) {
            log.debug("Illegal binlog status code {}, remaining packet \n{}", statusCode, readRemainPacket(payload));
        }
    }
    
    private String readRemainPacket(final MySQLPacketPayload payload) {
        return ByteBufUtil.hexDump(payload.readStringFixByBytes(payload.getByteBuf().readableBytes()));
    }
    
    private boolean checkEventIntegrity(final ByteBuf in, final MySQLBinlogEventHeader binlogEventHeader) {
        if (in.readableBytes() < binlogEventHeader.getEventSize() - MySQLBinlogEventHeader.MYSQL_BINLOG_EVENT_HEADER_LENGTH) {
            log.debug("the event body is not complete, event size={}, readable bytes={}", binlogEventHeader.getEventSize(), in.readableBytes());
            in.resetReaderIndex();
            return false;
        }
        return true;
    }

View on GitHub (pinned to e952770a21)

Solutions

  1. Read errorCode/sqlState/errorMessage from the exception — e.g. 1227/1236 map to privilege and binlog-availability problems — and fix that server-side condition.
  2. Grant REPLICATION SLAVE, REPLICATION CLIENT (and SELECT for the dump) to the pipeline user and restart the incremental task.
  3. 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.
  4. If the error is transient (restart), restart the pipeline job to re-request the stream from the recorded position.

Example fix

-- before: user lacks privileges
GRANT SELECT ON db.* TO 'pipeline'@'%';

-- after
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'pipeline'@'%';
Defensive patterns

Strategy: validation

Validate before calling

// preflight replication readiness on MySQL source
try (Statement st = sourceConnection.createStatement()) {
    ResultSet rs = st.executeQuery("SHOW VARIABLES LIKE 'log_bin'"); // must be ON
    ResultSet rs2 = st.executeQuery("SHOW MASTER STATUS");       // binlog exists
    ResultSet rs3 = st.executeQuery("SHOW GRANTS FOR CURRENT_USER()"); // must include REPLICATION SLAVE
}

Try / catch

try {
    channel.connect(); // binlog stream
} catch (final PipelineInternalException ex) {
    if (ex.getMessage().contains("Decode binlog event failed")) {
        // parse errorCode; 1236 -> purged binlog/privileges: re-anchor position or fix grants, then restart job
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/6735bc9396e87b4e. Report an issue: GitHub.