t8y2/dbx · error

read Kerberos JAAS config: %w

Error message

read Kerberos JAAS config: %w

What it means

This error wraps the underlying os.ReadFile failure when the driver tries to load a Kerberos JAAS config file whose path was given via kerberosConfig.JAASConfigPath. The %w preserves the OS-level cause (e.g. 'no such file or directory', 'permission denied') so callers can errors.Is/As the wrapped error. The library throws it because it cannot proceed to parse the Krb5LoginModule block without the file contents.

Source

Thrown at agents/drivers/argo-go/config.go:961

	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 JAAS config path exists and is readable by the process user (ls -l / stat)
  2. Fix the path in the config/connection string to the absolute location of the JAAS file
  3. Mount the JAAS file (e.g. Kubernetes secret volume) into the container at the expected path
  4. Check the error's wrapped cause (%w) to distinguish not-found vs permission issues and fix accordingly

Example fix

// before
jaasPath := "/etc/krb5/jaas.conf" // file not present
// after
if _, err := os.Stat(jaasPath); err != nil {
    log.Fatalf("JAAS config missing at %s: %v", jaasPath, err)
}
Defensive patterns

Strategy: validation

Validate before calling

if cfg.JAASConfigPath != "" {
    if fi, err := os.Stat(cfg.JAASConfigPath); err != nil || fi.IsDir() {
        return fmt.Errorf("Kerberos JAAS config not readable at %s", cfg.JAASConfigPath)
    }
}

Try / catch

if _, err := client.Connect(ctx); err != nil {
    var pathErr *os.PathError
    if errors.As(err, &pathErr) && errors.Is(err, os.ErrNotExist) {
        log.Fatalf("JAAS config missing: %s", pathErr.Path)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the driver's config/connect path with Kerberos enabled and a JAAS config path set (JAASConfigPath), where applyKerberosJAASFile fails on os.ReadFile — file missing, wrong path, or unreadable permissions.

Common situations: Typos in the JAAS config path in the connection string/config; file deployed on a different host than the driver; running the process under a service account lacking read permission; container image not mounting the secret containing the JAAS file.

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/1542fc10a4d687cc. Report an issue: GitHub.