{"record":{"id":"2e7f5b86d378e641","repo":"xai-org/x-algorithm","slug":"keytab-file-not-found-self-config-keytab-path","errorCode":null,"errorMessage":"Keytab file not found: {self.config.keytab_path}","messagePattern":"Keytab file not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"critical","filePath":"grox/libs/kerberos_cli/kerberos.py","lineNumber":26,"sourceCode":"logger = logging.getLogger(__name__)\n\n\nclass KerberosConfig(BaseModel):\n    keytab_path: str\n    principal: str\n    renew_interval: int = 3600\n    attempts: int = 5\n    retry_interval: int = 60\n\n\nclass KerberosRenewer:\n    def __init__(self, keytab_path: str, principal: str, **kwargs):\n        self._renewer: asyncio.Task | None = None\n        self.config = KerberosConfig(\n            keytab_path=keytab_path, principal=principal, **kwargs\n        )\n        if not Path(self.config.keytab_path).exists():\n            raise FileNotFoundError(f\"Keytab file not found: {self.config.keytab_path}\")\n        if self.config.renew_interval <= 0:\n            raise ValueError(\"Renew interval must be greater than 0\")\n        if self.config.attempts <= 0:\n            raise ValueError(\"Attempts must be greater than 0\")\n        if self.config.retry_interval <= 0:\n            raise ValueError(\"Retry interval must be greater than 0\")\n\n    async def _kerberos_renewal_loop(self):\n        while True:\n            attempts = self.config.attempts\n            while attempts > 0:\n                attempts -= 1\n                try:\n                    await self._renew_kerberos_ticket()\n                    logger.info(\n                        f\"Kerberos ticket renewed successfully for {self.config.principal}\"\n                    )\n                    break","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/grox/libs/kerberos_cli/kerberos.py#L8-L44","documentation":"KerberosClient.__init__ validates that the keytab file exists on disk before attempting any kinit. If Path(keytab_path) does not exist it raises FileNotFoundError with the configured path, so misconfigured paths fail at construction rather than deep inside the renewal loop.","triggerScenarios":"new KerberosClient(keytab_path='/etc/krb5/missing.keytab', ...) where the file is absent; also a relative path resolved against an unexpected working directory, or a secret not mounted in the container.","commonSituations":"k8s Secret not mounted / mounted at a different path; running locally where /etc/... does not exist; path from config with a typo or with $VAR placeholders unexpanded; container running as a user without read access making exists() effectively unusable later.","solutions":["Verify the path exists in the runtime: kubectl exec -- ls -l <path> or ls locally.","Mount the keytab Secret at the configured path (volumes/volumeMounts) or point keytab_path at the real location.","If templated, ensure env expansion happens before constructing the client."],"exampleFix":"# before\nclient = KerberosClient('/etc/secrets/krb5.keytab', 'svc@REALM')  # FileNotFoundError\n\n# after\n# mount the secret at /etc/secrets, then\nclient = KerberosClient('/etc/secrets/krb5.keytab', 'svc@REALM')","handlingStrategy":"validation","validationCode":"from pathlib import Path\nif not Path(keytab_path).is_file():\n    raise SystemExit(f'keytab missing: {keytab_path}')\nclient = KerberosClient(keytab_path, principal)","typeGuard":null,"tryCatchPattern":"try:\n    client = KerberosClient(kt, principal)\nexcept FileNotFoundError as e:\n    logger.error('keytab not mounted: %s', e)\n    raise","preventionTips":["Mount keytab Secrets with a fixed, absolute path","Add a container init check for the keytab file","Expand env vars in paths before constructing the client"],"tags":["kerberos","keytab","authentication","file-not-found","kubernetes"],"backgroundTag":"missing-credentials-file","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}