{"record":{"id":"ffc649bbfd18ad1a","repo":"alibaba/canal","slug":"command-show-binlog-events-limit-1-has-an-erro","errorCode":null,"errorMessage":"command : 'show binlog events limit 1' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation","messagePattern":"command : 'show binlog events limit 1' has an error! pls check\\. you need \\(at least one of\\) the SUPER,REPLICATION CLIENT privilege\\(s\\) for this operation","errorType":"exception","errorClass":"CanalParseException","httpStatus":null,"severity":"critical","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java","lineNumber":712,"sourceCode":"            return endPosition;\n        } catch (IOException e) {\n            throw new CanalParseException(\"command : '\" + showSql + \"' has an error!\", e);\n        }\n    }\n\n    /**\n     * 查询当前的binlog位置\n     */\n    private EntryPosition findStartPosition(MysqlConnection mysqlConnection) {\n        try {\n            String showSql = \"show binlog events limit 1\";\n            if (multiStreamEnable) {\n                showSql = \"show binlog events with \" + destination + \" limit 1\";\n            }\n            ResultSetPacket packet = mysqlConnection.query(showSql);\n            List<String> fields = packet.getFieldValues();\n            if (CollectionUtils.isEmpty(fields)) {\n                throw new CanalParseException(\n                        \"command : 'show binlog events limit 1' has an error! pls check. you need (at least one of) the SUPER,REPLICATION CLIENT privilege(s) for this operation\");\n            }\n            EntryPosition endPosition = new EntryPosition(fields.get(0), Long.valueOf(fields.get(1)));\n            return endPosition;\n        } catch (IOException e) {\n            throw new CanalParseException(\"command : 'show binlog events limit 1' has an error!\", e);\n        }\n\n    }\n\n    /**\n     * 查询当前的slave视图的binlog位置\n     */\n    @SuppressWarnings(\"unused\")\n    private SlaveEntryPosition findSlavePosition(MysqlConnection mysqlConnection) {\n        try {\n            String showSql = \"show slave status\";\n            if (mysqlConnection.atLeastMySQL84()) {","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/MysqlEventParser.java#L694-L730","documentation":"Thrown when findStartPosition() queries 'show binlog events limit 1' and the returned ResultSetPacket has no field values. Canal interprets an empty result as evidence that the MySQL account lacks SUPER or REPLICATION CLIENT privileges — MySQL returns an empty result set (rather than an explicit error) when the user is not permitted to read binlog events. The start position (binlog filename + offset) cannot be determined, so parsing cannot proceed.","triggerScenarios":"The MysqlEventParser calls mysqlConnection.query(\"show binlog events limit 1\") during startup position discovery. If packet.getFieldValues() is empty or null, this exception fires. Also triggered when multiStreamEnable uses the \"show binlog events with <destination> limit 1\" variant and the same empty-result condition holds.","commonSituations":"The canal.link user was granted only standard DML privileges (SELECT/INSERT/UPDATE/DELETE) without REPLICATION SLAVE or REPLICATION CLIENT. A DBA created the account for application use and forgot replication grants. On MySQL 8.0+ the privilege name changed and the grant was missed. On a read-replica, the replication user on the replica differs from the one on the primary.","solutions":["GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; then FLUSH PRIVILEGES on the MySQL server.","Verify the correct credentials are set in canal instance properties (canal.instance.dbUsername / canal.instance.dbPassword).","Test the grant by running 'SHOW BINLOG EVENTS LIMIT 1;' directly in the MySQL CLI as the canal user.","If on MySQL 8.0+, ensure the user uses the caching_sha2_password or mysql_native_password auth plugin that canal's driver supports."],"exampleFix":"-- before\nCREATE USER 'canal'@'%' IDENTIFIED BY '***';\nGRANT SELECT ON mydb.* TO 'canal'@'%';\n\n-- after\nCREATE USER 'canal'@'%' IDENTIFIED BY '***';\nGRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';\nFLUSH PRIVILEGES;","handlingStrategy":"validation","validationCode":"// Before starting the parser, verify replication privileges\nResultSetPacket rs = mysqlConnection.query(\"SHOW GRANTS FOR CURRENT_USER()\");\nList<String> grants = rs.getFieldValues();\nboolean hasReplicationPriv = grants.stream()\n    .anyMatch(g -> g.contains(\"REPLICATION CLIENT\") || g.contains(\"REPLICATION SLAVE\") || g.contains(\"SUPER\"));\nif (!hasReplicationPriv) {\n    throw new IllegalStateException(\"Canal user lacks REPLICATION SLAVE/CLIENT privilege\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    EntryPosition pos = findStartPosition(mysqlConnection);\n} catch (CanalParseException e) {\n    if (e.getMessage().contains(\"REPLICATION CLIENT privilege\")) {\n        // alert ops to grant privileges, do not retry until fixed\n        throw new ConfigurationException(\"MySQL user needs REPLICATION SLAVE, REPLICATION CLIENT\", e);\n    }\n    throw e;\n}","preventionTips":["Document the required MySQL grants in your Canal deployment runbook.","Add a startup health-check that runs SHOW GRANTS and verifies replication privileges before entering the main parse loop.","Use a dedicated MySQL account for Canal with only REPLICATION SLAVE, REPLICATION CLIENT, and SELECT."],"tags":["mysql","privileges","replication","binlog","startup"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}