alibaba/canal · error · RuntimeException

ERROR # The kafka kerberos configuration file does not exist

Error message

ERROR # The kafka kerberos configuration file does not exist! please check it

What it means

Thrown by CanalKafkaProducer.init when kerberos is enabled: it requires BOTH the krb5.conf file (java.security.krb5.conf) and the JAAS login file (java.security.auth.login.config) to exist on disk. If either File.exists() returns false, it logs the error and throws a RuntimeException before any SASL_PLAINTEXT properties are set, so the producer never starts.

Source

Thrown at connector/kafka-connector/src/main/java/com/alibaba/otter/canal/connector/kafka/producer/CanalKafkaProducer.java:78

        Properties kafkaProperties = new Properties();
        kafkaProperties.putAll(kafkaProducerConfig.getKafkaProperties());
        kafkaProperties.put("max.in.flight.requests.per.connection", 1);
        kafkaProperties.put("key.serializer", StringSerializer.class);
        if (kafkaProducerConfig.isKerberosEnabled()) {
            File krb5File = new File(kafkaProducerConfig.getKrb5File());
            File jaasFile = new File(kafkaProducerConfig.getJaasFile());
            if (krb5File.exists() && jaasFile.exists()) {
                // 配置kerberos认证,需要使用绝对路径
                System.setProperty("java.security.krb5.conf", krb5File.getAbsolutePath());
                System.setProperty("java.security.auth.login.config", jaasFile.getAbsolutePath());
                System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
                kafkaProperties.put("security.protocol", "SASL_PLAINTEXT");
                kafkaProperties.put("sasl.kerberos.service.name", "kafka");
            } else {
                String errorMsg = "ERROR # The kafka kerberos configuration file does not exist! please check it";
                logger.error(errorMsg);
                throw new RuntimeException(errorMsg);
            }
        }
        kafkaProperties.put("value.serializer", KafkaMessageSerializer.class);
        producer = new KafkaProducer<>(kafkaProperties);
    }

    private void loadKafkaProperties(Properties properties) {
        KafkaProducerConfig kafkaProducerConfig = (KafkaProducerConfig) this.mqProperties;
        Map<String, Object> kafkaProperties = kafkaProducerConfig.getKafkaProperties();
        // 兼容下<=1.1.4的mq配置
        doMoreCompatibleConvert("canal.mq.servers", "kafka.bootstrap.servers", properties);
        doMoreCompatibleConvert("canal.mq.acks", "kafka.acks", properties);
        doMoreCompatibleConvert("canal.mq.compressionType", "kafka.compression.type", properties);
        doMoreCompatibleConvert("canal.mq.retries", "kafka.retries", properties);
        doMoreCompatibleConvert("canal.mq.batchSize", "kafka.batch.size", properties);
        doMoreCompatibleConvert("canal.mq.lingerMs", "kafka.linger.ms", properties);
        doMoreCompatibleConvert("canal.mq.maxRequestSize", "kafka.max.request.size", properties);
        doMoreCompatibleConvert("canal.mq.bufferMemory", "kafka.buffer.memory", properties);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Verify both configured paths exist on the producer host: check kafkaProducerConfig.getKrb5File() and getJaasFile() values and run `ls -l` on each.
  2. Use absolute paths for the krb5/jaas file properties to avoid working-directory ambiguity.
  3. In containers, mount the kerberos config files and set the properties to the mounted absolute paths.
  4. If you do not actually need kerberos, clear the krb5/jaas config properties so the kerberos branch is skipped entirely.

Example fix

// before — relative paths, missing on deployed host
File krb5File = new File(kafkaProducerConfig.getKrb5File());

// after — validate and fail with a precise message before init
File krb5File = new File(kafkaProducerConfig.getKrb5File());
File jaasFile = new File(kafkaProducerConfig.getJaasFile());
if (!krb5File.exists()) {
    throw new IllegalArgumentException("krb5.conf not found at " + krb5File.getAbsolutePath());
}
if (!jaasFile.exists()) {
    throw new IllegalArgumentException("jaas.conf not found at " + jaasFile.getAbsolutePath());
}
Defensive patterns

Strategy: validation

Validate before calling

File krb5 = new File(kafkaProducerConfig.getKrb5File());
File jaas = new File(kafkaProducerConfig.getJaasFile());
if (!krb5.exists() || !jaas.exists()) {
    throw new IllegalStateException(
        "kerberos config missing: krb5=" + krb5.getAbsolutePath()
        + " exists=" + krb5.exists()
        + ", jaas=" + jaas.getAbsolutePath()
        + " exists=" + jaas.exists());
}

Prevention

When it happens

Trigger: kafkaProducerConfig.getKrb5File() or getJaasFile() points to a path that does not exist on the JVM host. The check is a strict AND: both must exist; missing either trips the branch.

Common situations: Deploying to a new host where the kerberos config paths differ; relative paths resolved against an unexpected working directory; containerized deployment that forgot to mount the krb5/jaas volumes; typo in canal.mq.kerberos.krb5.file / canal.mq.kerberos.jaas.file properties.

Related errors


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