{"record":{"id":"d23166b91b58da6e","repo":"alibaba/canal","slug":"failed-to-subscribe-with-reason","errorCode":null,"errorMessage":"failed to subscribe with reason: {}","messagePattern":"failed to subscribe with reason: (.+?)","errorType":"exception","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/connector/SimpleAdminConnector.java","lineNumber":220,"sourceCode":"    @Override\n    public String instanceLog(String destination, String fileName, int lines) {\n        return doLogAdmin(\"instance\", \"file\", destination, fileName, lines);\n    }\n\n    // ==================== helper method ====================\n\n    private String doServerAdmin(String action) {\n        try {\n            writeWithHeader(Packet.newBuilder()\n                .setType(PacketType.SERVER)\n                .setBody(ServerAdmin.newBuilder().setAction(action).build().toByteString())\n                .build()\n                .toByteArray());\n\n            Packet p = Packet.parseFrom(readNextPacket());\n            Ack ack = Ack.parseFrom(p.getBody());\n            if (ack.getCode() > 0) {\n                throw new ServiceException(\"failed to subscribe with reason: \" + ack.getMessage());\n            }\n\n            return ack.getMessage();\n        } catch (IOException e) {\n            throw new ServiceException(e);\n        }\n    }\n\n    private String doInstanceAdmin(String destination, String action) {\n        try {\n            writeWithHeader(Packet.newBuilder()\n                .setType(PacketType.INSTANCE)\n                .setBody(InstanceAdmin.newBuilder()\n                    .setDestination(destination)\n                    .setAction(action)\n                    .build()\n                    .toByteString())\n                .build()","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/connector/SimpleAdminConnector.java#L202-L238","documentation":"Thrown by doServerAdmin(String action) when a SERVER admin packet's ACK returns code > 0. The server rejected the requested server-level operation and supplied a reason message.","triggerScenarios":"Calling a server admin action (e.g. start/stop/reload server) over the connector; the server processes it and returns an ACK with positive error code, e.g. server not ready, already in that state, or lacking permission.","commonSituations":"Issuing a reload/start on a server that is down or mid-transition; the action is invalid for the server's current state; concurrent admin operations conflict; resource constraints on the server side.","solutions":["Read ack.getMessage() appended to the exception for the server's stated reason.","Retry after the server reaches a stable state (verify server liveness first).","Ensure no concurrent admin action is mutating the server simultaneously.","Check server-side logs for the failure detail behind the error code."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    connector.serverAdmin(action);\n} catch (ServiceException e) {\n    if (e.getMessage().contains(\"failed to subscribe\")) {\n        // transient server-state issue; wait for stable state then retry once\n    }\n    throw e;\n}","preventionTips":["Check server liveness/state before issuing admin actions.","Avoid concurrent admin operations on the same server.","Log the appended ack.getMessage() to capture the server's stated reason."],"tags":["canal-admin","server-management","rpc","admin-operation"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}