{"record":{"id":"b72d81b337014b9c","repo":"alibaba/canal","slug":"auth-is-failed","errorCode":null,"errorMessage":"auth : {} is failed","messagePattern":"auth : (.+?) is failed","errorType":"http","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/controller/PollingConfigController.java","lineNumber":48,"sourceCode":"    String                      user;\n\n    @Value(value = \"${canal.adminPasswd}\")\n    String                      passwd;\n\n    @Autowired\n    PollingConfigService        pollingConfigService;\n\n    /**\n     * 获取server全局配置\n     */\n    @GetMapping(value = \"/server_polling\")\n    public BaseModel<CanalConfig> canalConfigPoll(@RequestHeader String user, @RequestHeader String passwd,\n                                                  @RequestParam String ip, @RequestParam Integer port,\n                                                  @RequestParam String md5, @RequestParam boolean register,\n                                                  @RequestParam String cluster, @RequestParam String name,\n                                                  @PathVariable String env) {\n        if (!auth(user, passwd)) {\n            throw new RuntimeException(\"auth :\" + user + \" is failed\");\n        }\n\n        if (StringUtils.isEmpty(md5) && register) {\n            // do something\n            pollingConfigService.autoRegister(ip, port, cluster, StringUtils.trimToNull(name));\n        }\n\n        CanalConfig canalConfig = pollingConfigService.getChangedConfig(ip, port, md5);\n        return BaseModel.getInstance(canalConfig);\n    }\n\n    /**\n     * 获取单个instance的配置\n     */\n    @GetMapping(value = \"/instance_polling/{destination}\")\n    public BaseModel<CanalInstanceConfig> instanceConfigPoll(@RequestHeader String user, @RequestHeader String passwd,\n                                                             @PathVariable String env,\n                                                             @PathVariable String destination, @RequestParam String md5) {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/controller/PollingConfigController.java#L30-L66","documentation":"Thrown by canalConfigPoll() (GET /server_polling) when auth(user, passwd) returns false — the request's user/passwd headers don't satisfy the admin's configured credentials. Returns a generic RuntimeException.","triggerScenarios":"A canal-server polling for global config sends wrong/missing user or passwd headers; auth() compares them against the admin's this.user/this.passwd and fails, throwing 'auth :<user> is failed'.","commonSituations":"canal-server's canal.adminUser/canal.adminPasswd differ from canal-admin's; headers not sent by the polling client; trailing whitespace in the header value; password regenerated on one side only.","solutions":["Set identical canal.adminUser and canal.adminPasswd on canal-admin and every canal-server polling it.","Ensure the polling client actually sends the user/passwd request headers.","Trim/normalize credential values to avoid whitespace mismatch.","Note: if admin's configured passwd is empty, auth() allows any user — confirm that is not masking a config omission."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Polling client: send matching credentials\nHttpHeaders headers = new HttpHeaders();\nheaders.set(\"user\", adminUser);\nheaders.set(\"passwd\", adminPasswd);\nif (StringUtils.isBlank(adminUser) || StringUtils.isBlank(adminPasswd)) {\n    throw new IllegalStateException(\"admin credentials required for polling\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep admin credentials identical on admin and all polling servers.","Send user/passwd headers on every polling request.","Decide intentionally whether an empty admin passwd (which disables auth) is acceptable."],"tags":["auth","canal-admin","polling","rest-api","credentials"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}