{"record":{"id":"231c60d5453b1360","repo":"spring-projects/spring-security","slug":"your-keytab-is-in-the-classpath-this-file-needs-s","errorCode":null,"errorMessage":"Your keytab is in the classpath. This file needs special protection and shouldn't be in the classpath. JAAS may also not be able to load this file from classpath.","messagePattern":"Your keytab is in the classpath\\. This file needs special protection and shouldn't be in the classpath\\. JAAS may also not be able to load this file from classpath\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kerberos/kerberos-client/src/main/java/org/springframework/security/kerberos/client/config/SunJaasKrb5LoginConfig.java","lineNumber":81,"sourceCode":"\n\tpublic void setUseTicketCache(Boolean useTicketCache) {\n\t\tthis.useTicketCache = useTicketCache;\n\t}\n\n\tpublic void setIsInitiator(Boolean isInitiator) {\n\t\tthis.isInitiator = isInitiator;\n\t}\n\n\tpublic void setDebug(Boolean debug) {\n\t\tthis.debug = debug;\n\t}\n\n\t@Override\n\tpublic void afterPropertiesSet() throws Exception {\n\t\tAssert.hasText(this.servicePrincipal, \"servicePrincipal must be specified\");\n\n\t\tif (this.keyTabLocation != null && this.keyTabLocation instanceof ClassPathResource) {\n\t\t\tLOG.warn(\n\t\t\t\t\t\"Your keytab is in the classpath. This file needs special protection and shouldn't be in the classpath. JAAS may also not be able to load this file from classpath.\");\n\t\t}\n\n\t\tif (!this.useTicketCache) {\n\t\t\tAssert.notNull(this.keyTabLocation, \"keyTabLocation must be specified when useTicketCache is false\");\n\t\t}\n\n\t\tif (this.keyTabLocation != null) {\n\t\t\tthis.keyTabLocationAsString = this.keyTabLocation.getURL().toExternalForm();\n\t\t\tif (this.keyTabLocationAsString.startsWith(\"file:\")) {\n\t\t\t\tthis.keyTabLocationAsString = this.keyTabLocationAsString.substring(5);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic AppConfigurationEntry[] getAppConfigurationEntry(String name) {\n\t\tHashMap<String, String> options = new HashMap<>();","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/kerberos/kerberos-client/src/main/java/org/springframework/security/kerberos/client/config/SunJaasKrb5LoginConfig.java#L63-L99","documentation":"SunJaasKrb5LoginConfig.afterPropertiesSet logs this warning when the configured keyTabLocation is a ClassPathResource. A keytab holds long-lived Kerberos keys and must be protected on disk with restricted permissions; packaging it inside the classpath (JAR/WAR) both exposes it to anyone with the artifact and prevents JAAS from reliably reading it via Krb5LoginModule.","triggerScenarios":"Configuring SunJaasKrb5LoginConfig.setKeyTabLocation(new ClassPathResource(\"krb5.keytab\")) — or Spring Security Kerberos properties like spring.security.kerberos.service-principal/key-tab-location resolving to a classpath: location — then calling afterPropertiesSet (typically via the loginConfig bean factory method).","commonSituations":"Setting key-tab-location: classpath:krb5.keytab in application.yml; dropping the keytab in src/main/resources so it lands in the JAR; copying sample configs verbatim in Docker/Kubernetes deployments.","solutions":["Move the keytab outside the classpath (e.g. /etc/security/myapp.keytab) and reference it with a FileSystemResource or a file: URL.","Restrict file permissions to the service user (chown root:myapp && chmod 600 /etc/security/myapp.keytab).","Externalize the location via configuration (application.yml / K8s secret-mounted volume) instead of bundling the file in the artifact.","Regenerate the keytab with ktpass/kadmin if it was committed to source control, since it is now compromised."],"exampleFix":"// before\nconfig.setKeyTabLocation(new ClassPathResource(\"krb5.keytab\"));\n\n// after\nconfig.setKeyTabLocation(new FileSystemResource(\"/etc/security/myapp.keytab\"));\n// or application.yml: key-tab-location: file:/etc/security/myapp.keytab","handlingStrategy":"validation","validationCode":"Resource keytab = config.getKeyTabLocation();\nif (keytab instanceof ClassPathResource) {\n    throw new IllegalStateException(\"keyTabLocation must point outside the classpath (use FileSystemResource or file: URL)\");\n}","typeGuard":"boolean isExternalKeytab(Resource r) { return r != null && !(r instanceof ClassPathResource); }","tryCatchPattern":"This is only a LOG.warn, not an exception — afterPropertiesSet proceeds; catch nothing, instead fail your own startup validation if you detect a ClassPathResource.","preventionTips":["Never put keytab files under src/main/resources; keep them in /etc/security or a mounted secret.","Always use absolute file: URLs or FileSystemResource for keyTabLocation.","chmod 600 the keytab and restrict ownership to the service account.","Never commit keytabs to git; rotate keys if one leaks."],"tags":["kerberos","security","classpath","keytab","configuration"],"backgroundTag":"keytab-in-classpath","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}