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
- Verify both configured paths exist on the producer host: check kafkaProducerConfig.getKrb5File() and getJaasFile() values and run `ls -l` on each.
- Use absolute paths for the krb5/jaas file properties to avoid working-directory ambiguity.
- In containers, mount the kerberos config files and set the properties to the mounted absolute paths.
- 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
- Use absolute paths for krb5/jaas config files.
- In containers, mount the kerberos config files as volumes.
- Drop the kerberos config properties entirely if SASL/kerberos is not required.
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
- Pulsar Consumer subscriptName required
- error
- failed to parse host
- canal socketChannel netty not support ssl mode: {}
- Parse sql error
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/52bc52f886c49119.
Report an issue: GitHub.