{"record":{"id":"3d2bc3d363319139","repo":"t8y2/dbx","slug":"kerberos-keytab-s-contains-no-principals","errorCode":null,"errorMessage":"Kerberos keytab %s contains no principals","messagePattern":"Kerberos keytab (.+?) contains no principals","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/cassandra-go/kerberos.go","lineNumber":582,"sourceCode":"\treturn value, realm, nil\n}\n\nfunc principalFromKeytab(path string) (string, error) {\n\tloadedKeytab, err := keytab.Load(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"load Kerberos keytab %s: %w\", path, err)\n\t}\n\tprincipals := map[string]struct{}{}\n\tfor _, entry := range loadedKeytab.Entries {\n\t\tprincipals[entry.Principal.String()] = struct{}{}\n\t}\n\tif len(principals) != 1 {\n\t\treturn \"\", fmt.Errorf(\"Kerberos keytab %s contains %d principals; configure kerberosprincipal explicitly\", path, len(principals))\n\t}\n\tfor principal := range principals {\n\t\treturn principal, nil\n\t}\n\treturn \"\", fmt.Errorf(\"Kerberos keytab %s contains no principals\", path)\n}\n\nfunc defaultKerberosConfigPath() string {\n\tif runtime.GOOS == \"windows\" {\n\t\tif windowsDirectory := os.Getenv(\"WINDIR\"); windowsDirectory != \"\" {\n\t\t\treturn filepath.Join(windowsDirectory, \"krb5.ini\")\n\t\t}\n\t}\n\treturn \"/etc/krb5.conf\"\n}\n\nfunc defaultKerberosCCachePath() string {\n\tif value := os.Getenv(\"KRB5CCNAME\"); value != \"\" {\n\t\treturn value\n\t}\n\tcurrentUser, err := user.Current()\n\tif err == nil && currentUser.Uid != \"\" {\n\t\treturn filepath.Join(os.TempDir(), \"krb5cc_\"+currentUser.Uid)","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/cassandra-go/kerberos.go#L564-L600","documentation":"principalFromKeytab returns this when the keytab parsed successfully but contains zero entries, so no principal can be derived from it. Since automatic principal discovery is impossible, credential selection fails.","triggerScenarios":"selectKeytabCredential runs with kerberosprincipal unset and loadedKeytab.Entries is empty (the for-loop over principals never executes, falling through to the final return).","commonSituations":"A keytab file created by an interrupted or failed ktpass/ktutil export; a keytab that had its entries removed with ktutil remove_entry; an empty or placeholder file that still parses as a valid keytab; provisioning scripts that create the file before populating it.","solutions":["Regenerate the keytab with proper entries (ktutil addent + wkt, or ktpass/kadmin ktadd).","Verify with klist -k <path> that at least one entry exists.","Set kerberosprincipal explicitly if you want the driver to proceed regardless, though authentication will still fail with an empty keytab — fixing the file is required."],"exampleFix":"// before\n$ klist -k /path/to.keytab  ->  (no entries)\n// after (regenerate)\n$ ktutil: addent -password -p svc-cassandra@EXAMPLE.COM -k 1 -en aes256-cts-hmac-sha1-96\n$ ktutil: wkt /path/to.keytab","handlingStrategy":"validation","validationCode":"info, err := os.Stat(keytabPath)\nif err != nil { return err }\nif info.Size() == 0 { return fmt.Errorf(\"keytab %s is empty\", keytabPath) }\nout, _ := exec.Command(\"klist\", \"-k\", keytabPath).Output()\nif len(strings.Fields(string(out))) == 0 { return fmt.Errorf(\"keytab has no entries\") }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"contains no principals\") {\n    return fmt.Errorf(\"keytab %s invalid; regenerate with ktutil/ktpass\", keytabPath)\n}","preventionTips":["Validate keytab contents with klist -k right after generation in provisioning scripts.","Fail fast at startup if the keytab has zero entries.","Avoid hand-editing keytabs; always generate via kadmin/ktpass/ktutil."],"tags":["kerberos","keytab","authentication"],"backgroundTag":"kerberos-keytab-empty","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}