alibaba/canal · critical · IllegalArgumentException

canal.adminPasswd is empty , pls check https://github.com/al

Error message

canal.adminPasswd is empty , pls check https://github.com/alibaba/canal/issues/4941

What it means

Thrown at startup when `canal.adminPasswd` is empty. WebConfig.addInterceptors() guards both credentials; an empty password aborts interceptor registration, blocking application boot.

Source

Thrown at admin/admin-web/src/main/java/com/alibaba/otter/canal/admin/config/WebConfig.java:45

 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Value(value = "${canal.adminUser}")
    private String user;

    @Value(value = "${canal.adminPasswd}")
    private String passwd;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        if (StringUtils.isEmpty(user)) {
            throw new IllegalArgumentException(
                "canal.adminUser is empty , pls check https://github.com/alibaba/canal/issues/4941");
        }

        if (StringUtils.isEmpty(passwd)) {
            throw new IllegalArgumentException(
                "canal.adminPasswd is empty , pls check https://github.com/alibaba/canal/issues/4941");
        }

        registry.addInterceptor(new HandlerInterceptor() {

            @Override
            public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                     Object o) throws Exception {
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
                httpServletResponse.setHeader("Access-Control-Allow-Headers",
                    "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Token");
                httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
                httpServletResponse.setHeader("Access-Control-Max-Age", String.valueOf(3600 * 24));

                if (HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())) {
                    httpServletResponse.setStatus(HttpStatus.NO_CONTENT.value());
                    return false;

View on GitHub (pinned to 87be50e876)

Solutions

  1. Set `canal.adminPasswd` in application.yml or via -Dcanal.adminPasswd=....
  2. Ensure the value is the same admin password configured in the canal-server side (they must match).
  3. If using external secret injection, verify the secret mounted/loaded before the Spring context initializes.
  4. Refer to GitHub issue #4941 for the full credential-pair setup.

Example fix

// before
canal:
  adminUser: admin
  adminPasswd: ""

// after
canal:
  adminUser: admin
  adminPasswd: your-password
Defensive patterns

Strategy: validation

Validate before calling

if (org.apache.commons.lang.StringUtils.isBlank(System.getProperty("canal.adminPasswd"))) {
    throw new IllegalStateException("canal.adminPasswd must be set before startup");
}

Prevention

When it happens

Trigger: Boot the admin web app with `canal.adminPasswd` unset/empty. The @Value("${canal.adminPasswd}") field is empty, so the second StringUtils.isEmpty check throws IllegalArgumentException.

Common situations: Password property omitted from config; only adminUser set; placeholder not substituted in templated config; secret-management injection (Vault/K8s secret) failed silently leaving blank.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/2c2e3b48f18bfc99. Report an issue: GitHub.