t8y2/dbx · error
Kerberos realm is required for principal %s
Error message
Kerberos realm is required for principal %s
What it means
The principal had no '@' realm suffix and no realm could be supplied from the configured realm or the krb5.conf default_realm, so the principal cannot be fully qualified for Kerberos auth. Kerberos requires a realm; the library refuses to guess.
Source
Thrown at agents/drivers/cassandra-go/kerberos.go:562
}
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{}{}
}
if len(principals) != 1 {
return "", fmt.Errorf("Kerberos keytab %s contains %d principals; configure kerberosprincipal explicitly", path, len(principals))
}
for principal := range principals {
return principal, nilView on GitHub (pinned to c0390bff16)
Solutions
- Include the realm in the principal: svc-cassandra@EXAMPLE.COM.
- Set the driver's kerberosrealm config option (or JAAS realm) to EXAMPLE.COM.
- Fix /etc/krb5.conf (or KRB5_CONFIG target) to define default_realm = EXAMPLE.COM so the default can be applied.
- Confirm the realm matches the KDC's realm, case-sensitive uppercase by convention.
Example fix
// before principal="svc-cassandra" // after principal="svc-cassandra@EXAMPLE.COM" // or set kerberosrealm="EXAMPLE.COM"
Defensive patterns
Strategy: validation
Validate before calling
func principalHasRealm(p, configuredRealm string) bool {
if strings.Contains(p, "@") { return true }
return strings.TrimSpace(configuredRealm) != ""
}
// plus confirm /etc/krb5.conf has default_realm set when relying on the default Type guard
func hasRealm(p string) bool {
at := strings.LastIndexByte(strings.TrimSpace(p), '@')
return at >= 0 && at < len(p)-1
} Try / catch
if err := client.Finalize(); err != nil {
if strings.Contains(err.Error(), "realm is required for principal") {
log.Fatalf("qualify principal with @REALM or set kerberosrealm/default_realm")
}
return err
} Prevention
- Always use fully qualified principals (user@REALM).
- Set kerberosrealm explicitly in the driver config for services.
- Ensure krb5.conf with default_realm is present in containers.
- Validate realms are uppercase and match the KDC.
When it happens
Trigger: splitKerberosPrincipal receives `svc-cassandra` (no @REALM), configuredRealm is empty, and defaultRealm (from krb5.conf parsing) is also empty — e.g. krb5.conf missing/unreadable or lacking default_realm.
Common situations: Short-form principals in configs; krb5.conf not mounted in containers so default_realm is unknown; missing kerberosrealm config option; cross-realm setups where only the short name was given.
Related errors
- Kerberos principal is empty
- invalid usekrb5 option: %w
- invalid disablepafxfast option: %w
- invalid usekeytab option: %w
- invalid useticketcache option: %w
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/a08a8543a36e2b14.
Report an issue: GitHub.