{"record":{"id":"108e7861a314fe9a","repo":"alibaba/canal","slug":"load-manager-config-failed","errorCode":null,"errorMessage":"load manager config failed.","messagePattern":"load manager config failed\\.","errorType":"exception","errorClass":"CanalException","httpStatus":null,"severity":"error","filePath":"instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/plain/PlainCanalConfigClient.java","lineNumber":114,"sourceCode":"        if (StringUtils.isEmpty(md5)) {\n            md5 = \"\";\n        }\n        String url = configURL + \"/api/v1/config/instances_polling?md5=\" + md5 + \"&ip=\" + localIp + \"&port=\"\n                     + adminPort;\n        ResponseModel<CanalConfig> config = doQuery(url);\n        if (config.data != null) {\n            return config.data.content;\n        } else {\n            return null;\n        }\n    }\n\n    private PlainCanal queryConfig(String url) {\n        try {\n            ResponseModel<CanalConfig> config = doQuery(url);\n            return processData(config.data);\n        } catch (Throwable e) {\n            throw new CanalException(\"load manager config failed.\", e);\n        }\n    }\n\n    private ResponseModel<CanalConfig> doQuery(String url) {\n        Map<String, String> heads = new HashMap<>();\n        heads.put(\"user\", user);\n        heads.put(\"passwd\", passwd);\n        String response = httpHelper.get(url, heads, REQUEST_TIMEOUT);\n        ResponseModel<CanalConfig> resp = JSON.parseObject(response,\n            new TypeReference<ResponseModel<CanalConfig>>() {\n            });\n\n        if (!HttpHelper.REST_STATE_OK.equals(resp.code)) {\n            throw new CanalException(\"requestGet for canal config error: \" + resp.message);\n        }\n\n        return resp;\n    }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/plain/PlainCanalConfigClient.java#L96-L132","documentation":"Thrown by PlainCanalConfigClient.queryConfig as a catch-all wrapper around any Throwable raised while fetching remote canal/instance config from the Canal Admin server. It signals that the HTTP GET + JSON parse + post-process pipeline failed for an unhandled reason (network, timeout, malformed JSON, or the inner requestGet error 361). The original cause is attached as the exception's cause so the real failure is inspectable via getCause().","triggerScenarios":"Calling PlainCanalConfigClient.findServer(md5), findInstance(destination, md5), or findInstances(md5). These build a URL against configURL and call queryConfig(url), which calls doQuery(url). Any Throwable escaping doQuery (httpHelper.get throwing, JSON.parseObject failing, REST_STATE_OK mismatch) or processData (IOException/NoSuchAlgorithmException) gets wrapped into this CanalException.","commonSituations":"Canal Server is configured with canal.manager configuration pointing at an Admin URL that is unreachable, wrong port, firewall blocking, TLS mismatch, wrong user/passwd, or the Admin server is down. Also when the Admin returns a non-200 JSON or HTML error page that fastjson2 cannot deserialize into ResponseModel<CanalConfig>.","solutions":["Inspect the attached cause (e.getCause()) in logs to see the real failure (ConnectException, SocketTimeoutException, JSONException) before changing anything.","Verify the Admin server is up and reachable: curl the configURL endpoint /api/v1/config/server_polling from the Canal Server host with the same user/passwd headers.","Correct canal.manager.* properties in canal.properties (configURL host/port, user, passwd) so they match the Canal Admin deployment.","If the cause is JSON parse error, check the Admin server version matches the Canal Server version (the ResponseModel contract changed across releases) and that no proxy/interceptor is rewriting the response body."],"exampleFix":"// before\ncanal.instance.global.manager.address = wrong-host:8089\n\n// after (point at the running Canal Admin and supply credentials)\ncanal.manager.servers = admin-host:8089\ncanal.manager.user = admin\ncanal.manager.password = ********","handlingStrategy":"try-catch","validationCode":"// before constructing the client, sanity-check the admin endpoint\njava.net.URL u = new java.net.URL(configURL + \"/api/v1/config/server_polling?ip=127.0.0.1&port=11110&md5=&register=0&cluster=&name=\");\ntry (java.net.Socket s = new java.net.Socket()) {\n    s.connect(new java.net.InetSocketAddress(u.getHost(), u.getPort() < 0 ? 80 : u.getPort()), 3000);\n} // throws if unreachable -> do not start client","typeGuard":null,"tryCatchPattern":"try {\n    PlainCanal config = configClient.findServer(md5);\n} catch (CanalException e) {\n    log.error(\"admin config fetch failed (cause={})\", e.getCause() == null ? e.getMessage() : e.getCause().toString());\n    // fall back to last known-good local config or halt startup\n}","preventionTips":["Point canal.manager.* at a running Canal Admin reachable from the Canal Server host.","Run a release-matched pair of Admin and Server so the ResponseModel contract is stable.","Log e.getCause() to distinguish transport vs application failures."],"tags":["config","network","canal-admin","remote-config"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}