t8y2/dbx · error

read Kerberos JAAS config: %w

Error message

read Kerberos JAAS config: %w

What it means

This error wraps an os.ReadFile failure when loading the Kerberos JAAS config file specified by the jaasConfigPath setting. The driver reads this file to extract Krb5LoginModule options (principal, keytab, ticketCache) for Kerberos authentication. The wrapped error will be an os-level error (file not found, permission denied), so the JAAS file could not be opened at all.

Source

Thrown at agents/drivers/hive-go/config.go:964

	if kerberos.KeytabPath != "" {
		kerberos.UseKeytab = true
	}
	if kerberos.CCachePath != "" {
		kerberos.UseTicketCache = true
	}
	kerberos.Realm = firstNonEmpty(kerberos.Realm, realmFromPrincipal(kerberos.ClientPrincipal))
	if !kerberos.UseTicketCache && !kerberos.UseKeytab && (kerberos.ClientPrincipal == "" || kerberos.Password == "") {
		return errors.New("Kerberos requires SSPI, credential cache, keytab, or principal and password")
	}
	return nil
}

var jaasOptionPattern = regexp.MustCompile(`(?i)\b(principal|keytab|ticketcache|usekeytab|useticketcache)\s*=\s*("(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^\s;]+)`)

func applyKerberosJAASFile(config *kerberosConfig) error {
	contents, err := os.ReadFile(config.JAASConfigPath)
	if err != nil {
		return fmt.Errorf("read Kerberos JAAS config: %w", err)
	}
	text := string(contents)
	module := strings.Index(strings.ToLower(text), "krb5loginmodule")
	if module < 0 {
		return errors.New("Kerberos JAAS config contains no Krb5LoginModule")
	}
	block := text[module:]
	if end := strings.IndexByte(block, ';'); end >= 0 {
		block = block[:end]
	}
	for _, match := range jaasOptionPattern.FindAllStringSubmatch(block, -1) {
		key := strings.ToLower(match[1])
		value := decodeJAASValue(match[2])
		switch key {
		case "principal":
			if config.ClientPrincipal == "" {
				config.ClientPrincipal = value
			}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Verify the file exists at the configured path (ls/stat) and fix the jaasConfigPath value
  2. Grant the running user read permission on the JAAS file (chmod/chown or group membership)
  3. In containers, confirm the file is mounted (K8s secret volume) at the exact configured path

Example fix

// before
cfg.Kerberos.JAASConfigPath = "/etc/secrets/jaas.conf" // not mounted
// after
cfg.Kerberos.JAASConfigPath = "/mnt/kerberos/jaas.conf" // actual mount point
Defensive patterns

Strategy: validation

Validate before calling

path := cfg.Kerberos.JAASConfigPath
if _, err := os.Stat(path); err != nil {
	return fmt.Errorf("JAAS config unavailable: %w", err)
} else if f, err := os.OpenFile(path, os.O_RDONLY, 0); err != nil {
	return fmt.Errorf("JAAS config unreadable: %w", err)
} else { f.Close() }

Try / catch

err := cfg.ApplyKerberosFromJAAS(path)
if err != nil {
	var perr *fs.PathError
	if errors.As(err, &perr) {
		return fmt.Errorf("fix JAAS path/permissions: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Setting jaasConfigPath to a nonexistent path, a path the process cannot read (permissions), or a path inside a container/image that lacks the file.

Common situations: Mounting the keytab/JAAS file at a different path than configured; running the app as a non-root user without read access to /etc/krb5-related files; Docker/K8s secret not mounted; typo in the configured path.

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


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/fdff3c97665205b3. Report an issue: GitHub.