t8y2/dbx · error

Kerberos principal is empty

Error message

Kerberos principal is empty

What it means

splitKerberosPrincipal splits a Kerberos principal into user part and realm (on the last '@') and rejects an empty user part. The principal string was empty/whitespace, or consisted solely of a realm like `@EXAMPLE.COM`, so there is no principal name to authenticate with.

Source

Thrown at agents/drivers/cassandra-go/kerberos.go:556

	if strings.HasPrefix(strings.ToUpper(value), "FILE:") {
		value = value[5:]
	}
	path, err := normalizeLocalFilePath(value)
	if err != nil {
		return "", fmt.Errorf("invalid Kerberos file path: %w", err)
	}
	return path, nil
}

func splitKerberosPrincipal(principal, configuredRealm, defaultRealm string) (string, string, error) {
	value := strings.TrimSpace(principal)
	realm := strings.TrimSpace(configuredRealm)
	if separator := strings.LastIndexByte(value, '@'); separator >= 0 {
		realm = value[separator+1:]
		value = value[:separator]
	}
	if value == "" {
		return "", "", fmt.Errorf("Kerberos principal is empty")
	}
	if realm == "" {
		realm = strings.TrimSpace(defaultRealm)
	}
	if realm == "" {
		return "", "", fmt.Errorf("Kerberos realm is required for principal %s", principal)
	}
	return value, realm, nil
}

func principalFromKeytab(path string) (string, error) {
	loadedKeytab, err := keytab.Load(path)
	if err != nil {
		return "", fmt.Errorf("load Kerberos keytab %s: %w", path, err)
	}
	principals := map[string]struct{}{}
	for _, entry := range loadedKeytab.Entries {
		principals[entry.Principal.String()] = struct{}{}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Set the principal explicitly, e.g. cassandra/host@EXAMPLE.COM, in the driver config or JAAS `principal=` option.
  2. If the principal should come from the keytab, remove the empty setting so principalFromKeytab can derive it (requires a single-principal keytab).
  3. Fix template/env interpolation so KERBEROS_PRINCIPAL-like variables resolve to a non-empty value.
  4. Verify the string has a non-empty part before the last '@'.

Example fix

// before
principal="@EXAMPLE.COM"
// after
principal="svc-cassandra@EXAMPLE.COM"
Defensive patterns

Strategy: validation

Validate before calling

func validatePrincipal(p string) error {
	p = strings.TrimSpace(p)
	if p == "" { return fmt.Errorf("principal not set") }
	if strings.HasPrefix(p, "@") { return fmt.Errorf("principal missing user part") }
	return nil
}

Type guard

func hasPrincipalUserPart(p string) bool {
	p = strings.TrimSpace(p)
	at := strings.LastIndexByte(p, '@')
	return len(p) > 0 && (at != 0)
}

Try / catch

if err := client.Finalize(); err != nil {
	if strings.Contains(err.Error(), "Kerberos principal is empty") {
		log.Fatal("set kerberosprincipal (e.g. svc@EXAMPLE.COM) or use a single-principal keytab")
	}
	return err
}

Prevention

When it happens

Trigger: finalize/selectKeytabCredential call splitKerberosPrincipal with a principal that trims to empty, or with `@REALM` only; e.g. kerberosprincipal config/JAAS `principal=` empty while keytab auth requires one and the keytab could not supply a unique principal.

Common situations: Empty `principal=""` in config; JAAS `principal=` with no value; env-var interpolation that resolved to an empty string in a deployment template; typo leaving only the realm.

Related errors


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