{"record":{"id":"c1a0589c51677c76","repo":"alibaba/canal","slug":"error-when-doing-register-slave-err-tostring","errorCode":null,"errorMessage":"Error When doing Register slave: + err.toString()","messagePattern":"Error When doing Register slave: \\+ err\\.toString\\(\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlConnection.java","lineNumber":339,"sourceCode":"        cmd.reportUser = authInfo.getUsername();\n        cmd.serverId = this.slaveId;\n        byte[] cmdBody = cmd.toBytes();\n\n        logger.info(\"Register slave {}\", cmd);\n\n        HeaderPacket header = new HeaderPacket();\n        header.setPacketBodyLength(cmdBody.length);\n        header.setPacketSequenceNumber((byte) 0x00);\n        PacketManager.writePkg(connector.getChannel(), header.toBytes(), cmdBody);\n\n        header = PacketManager.readHeader(connector.getChannel(), 4);\n        byte[] body = PacketManager.readBytes(connector.getChannel(), header.getPacketBodyLength());\n        assert body != null;\n        if (body[0] < 0) {\n            if (body[0] == -1) {\n                ErrorPacket err = new ErrorPacket();\n                err.fromBytes(body);\n                throw new IOException(\"Error When doing Register slave:\" + err.toString());\n            } else {\n                throw new IOException(\"Unexpected packet with field_count=\" + body[0]);\n            }\n        }\n    }\n\n    private void sendBinlogDump(String binlogfilename, Long binlogPosition) throws IOException {\n        BinlogDumpCommandPacket binlogDumpCmd = new BinlogDumpCommandPacket();\n        binlogDumpCmd.binlogFileName = binlogfilename;\n        binlogDumpCmd.binlogPosition = binlogPosition;\n        binlogDumpCmd.slaveServerId = this.slaveId;\n        byte[] cmdBody = binlogDumpCmd.toBytes();\n\n        logger.info(\"COM_BINLOG_DUMP with position:{}\", binlogDumpCmd);\n        HeaderPacket binlogDumpHeader = new HeaderPacket();\n        binlogDumpHeader.setPacketBodyLength(cmdBody.length);\n        binlogDumpHeader.setPacketSequenceNumber((byte) 0x00);\n        PacketManager.writePkg(connector.getChannel(), binlogDumpHeader.toBytes(), cmdBody);","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlConnection.java#L321-L357","documentation":"During sendRegisterSlave(), after sending the COM_REGISTER_SLAVE packet the server replied with an error packet (first byte == -1, i.e. 0xff). Canal decodes it as an ErrorPacket and throws an IOException carrying the server's error text. This is a server-side rejection of the slave-registration handshake that precedes a binlog dump.","triggerScenarios":"The MySQL/MariaDB server returns error 0xff to COM_REGISTER_SLAVE. Typical causes: the connecting user lacks REPLICATION SLAVE privilege, the reported slave host/port is rejected, server_id collision, max replication connections reached, or skip-name-resolve / firewall rejecting the reported host.","commonSituations":"Account used by canal does not have GRANT REPLICATION SLAVE, REPLICATION CLIENT; another canal/replica already registered the same server_id; the reported reportHost resolves to something the master refuses (DNS / bind-address).","solutions":["Grant the replication account: GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'.","Ensure canal.instance.slaveId is unique across all replicas connected to the same master (collision yields a server-side error).","Check the embedded err.toString() in the exception for the exact MySQL error code/message and address that specifically (e.g. ER_MASTER_FATAL_ERROR_READING_BINLOG, host rejection).","If the master enforces skip-name-resolve, ensure canal's reported host matches an allowed host entry."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Around the dump/start that triggers sendRegisterSlave()\ntry {\n    connection.dump(journalName, position, coprocessor);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Register slave\")) {\n        logger.error(\"Slave registration rejected by master; check REPLICATION SLAVE privilege and server_id uniqueness\", e);\n        // surface a clear ops error, do not silently retry in a tight loop\n    }\n    throw e;\n}","preventionTips":["Grant the canal account REPLICATION SLAVE and REPLICATION CLIENT before first connect.","Assign a globally unique canal.instance.slaveId.","Run `SHOW PROCESSLIST` on the master to detect duplicate server_id registrations.","Ensure the canal host is allowed by the master's replication host filters / skip-name-resolve."],"tags":["mysql","replication","register-slave","privilege","network","canal-parse"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}