apache/beam · error · RuntimeException
Could not access keytab file. Make sure that the sasl.jaas.c
Error message
Could not access keytab file. Make sure that the sasl.jaas.config config property is set correctly.
What it means
After downloading the keytab to a local path, KerberosConsumerFactoryFn tightens its POSIX permissions to owner-read-only. If Files.setPosixFilePermissions throws IOException (file missing or filesystem without POSIX support), it rethrows a RuntimeException telling the user to check sasl.jaas.config. The message points at the config because the local keytab path derives from it.
Source
Thrown at sdks/java/extensions/kafka-factories/src/main/java/org/apache/beam/sdk/extensions/kafka/factories/KerberosConsumerFactoryFn.java:80
// property will have had it's value replaced with a local directory.
// We don't need to worry about the external bucket prefix in this case.
try {
String jaasConfig = (String) config.get(JAAS_CONFIG_PROPERTY);
String localKeytabPath = "";
if (jaasConfig != null && !jaasConfig.isEmpty()) {
localKeytabPath =
jaasConfig.substring(
jaasConfig.indexOf("keyTab=\"") + 8, jaasConfig.lastIndexOf("\" principal"));
}
// Set the permissions on the file to be as strict as possible for security reasons. The
// keytab contains sensitive information and should be as locked down as possible.
Path path = Paths.get(localKeytabPath);
Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
Files.setPosixFilePermissions(path, perms);
} catch (IOException e) {
throw new RuntimeException(
"Could not access keytab file. Make sure that the sasl.jaas.config config property "
+ "is set correctly.",
e);
}
return new KafkaConsumer<>(config);
}
@Override
protected void downloadAndProcessExtraFiles() throws IOException {
synchronized (lock) {
// we only want a new krb5 file if there is not already one present.
if (localKrb5ConfPath.isEmpty()) {
if (this.krb5ConfigPath != null && !this.krb5ConfigPath.isEmpty()) {
String localPath =
super.getBaseDirectory() + "/" + LOCAL_FACTORY_TYPE + "/" + "krb5.conf";
localKrb5ConfPath = downloadExternalFile(this.krb5ConfigPath, localPath);
System.setProperty("java.security.krb5.conf", localKrb5ConfPath);View on GitHub (pinned to 12126d8942)
Solutions
- Verify sasl.jaas.config correctly references the keytab secret so the file is downloaded to localKeytabPath before this code runs
- Check the chained IOException cause — FileNotFoundException means the keytab never landed at localKeytabPath
- Ensure the worker staging directory is on a POSIX-supporting filesystem
- Log/inspect localKeytabPath and confirm the file exists before constructing the consumer
Example fix
// before
props.put("sasl.jaas.config", "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab=\"MISSING\" ...");
// after
props.put("sasl.jaas.config", "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab=\"/tmp/keytab-<factory>/krb5.keytab\" ..."); // path produced by secret processing Defensive patterns
Strategy: try-catch
Validate before calling
java
if (!config.containsKey("sasl.jaas.config") || config.get("sasl.jaas.config").isEmpty()) {
throw new IllegalArgumentException("sasl.jaas.config must be set with a valid keyTab path");
} Try / catch
java
try {
KafkaConsumer<String,String> c = factoryFn.createObject(config);
} catch (RuntimeException ex) {
if (ex.getMessage().startsWith("Could not access keytab file")) {
log.severe("Keytab inaccessible at local path: " + ex.getCause());
}
} Prevention
- Verify the keytab secret downloads successfully before permissions are set
- Use POSIX-capable volumes in worker images
- Log the resolved localKeytabPath and assert file existence
- Keep sasl.jaas.config keyTab path in sync with the factory's local path convention
When it happens
Trigger: The keytab referenced in sasl.jaas.config was not written to localKeytabPath (secret processing failed or path mismatch), or the worker filesystem (e.g. some Windows/network mounts) doesn't support POSIX permissions.
Common situations: Missing or empty sasl.jaas.config key; secret download silently skipped; container using a volume that doesn't support POSIX perms; typo'd keytab path template.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Error matching values. Secret was discovered but its value i
- Unable to create the keytab file for the provided secret.
- Unknown DirectoryTreatment: " + directoryTreatment
- Unable to infer a coder for destination type (inferred from
- Failed trying to process value for key %s.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/efd9e547d1f5dc36.
Report an issue: GitHub.