{"record":{"id":"312bb66c1af661d1","repo":"apereo/cas","slug":"principal-is-null-the-processing-of-the-spnego-to","errorCode":null,"errorMessage":"Principal is null, the processing of the SPNEGO Token failed","messagePattern":"Principal is null, the processing of the SPNEGO Token failed","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java","lineNumber":112,"sourceCode":"\n        if (nextToken != null) {\n            LOGGER.debug(\"Setting nextToken in credential\");\n            spnegoCredential.setNextToken(nextToken);\n        } else {\n            LOGGER.debug(\"nextToken is null\");\n        }\n        var success = false;\n        if (principal != null) {\n            if (spnegoCredential.isNtlm()) {\n                LOGGER.debug(\"NTLM Credential is valid for user [{}]\", principal.getName());\n            } else {\n                LOGGER.debug(\"Kerberos Credential is valid for user [{}]\", principal.getName());\n            }\n            spnegoCredential.setPrincipal(getPrincipal(principal.getName(), spnegoCredential.isNtlm()));\n            success = true;\n        }\n        if (!success) {\n            throw new FailedLoginException(\"Principal is null, the processing of the SPNEGO Token failed\");\n        }\n        return new DefaultAuthenticationHandlerExecutionResult(this, spnegoCredential, spnegoCredential.getPrincipal());\n    }\n\n    @Override\n    public boolean supports(final Credential credential) {\n        return credential instanceof SpnegoCredential;\n    }\n\n    @Override\n    public boolean supports(final Class<? extends Credential> clazz) {\n        return SpnegoCredential.class.isAssignableFrom(clazz);\n    }\n\n    protected @Nullable Principal getPrincipal(final String name, final boolean isNtlm) throws Throwable {\n        if (spnegoProperties.isPrincipalWithDomainName()) {\n            return this.principalFactory.createPrincipal(name);\n        }","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java#L94-L130","documentation":"After running the JCIFS SPNEGO/NTLM handshake, doInternalAuthentication expects theJCIFS library to produce a non-null java.security.Principal representing the authenticated user. If processing the client token yields no principal (success flag stays false), the token was invalid or the handshake failed, so FailedLoginException is thrown.","triggerScenarios":"Client presents a SPNEGO/NTLM token that JCIFS cannot validate: wrong credentials, replayed/expired token, misconfigured jcifs.spengo.* / kerberos settings, or the DC rejects the token.","commonSituations":"Incorrect service password/krb5 keytab; SPN mismatch between requested host and registered SPN; clock skew between CAS server and KDC; jcifs domain/controller settings pointing at the wrong DC.","solutions":["Verify jcifs properties: jcifs.smb.client.domain, domain controller address, and the service account password used by the authentications pool.","Check SPN registration for the CAS host (setspn -L) matches the URL used by clients.","Synchronize clocks with the KDC (kerberos tolerance is typically 5 minutes).","Enable JCIFS debug logging (log4j config for jcifs) to see the underlying token-processing failure."],"exampleFix":"// before\ncas.authn.spnego.jcifs.domain-controller=old-dc.corp.local\n// after\ncas.authn.spnego.jcifs.domain-controller=dc1.corp.local","handlingStrategy":"try-catch","validationCode":"// pre-checks: SPN + clock sync\nkvno HTTP/cas.example.org@CORP.LOCAL\nntpdate -q dc1.corp.local","typeGuard":null,"tryCatchPattern":"try {\n    return handler.authenticate(credential);\n} catch (FailedLoginException e) {\n    if (e.getMessage().contains(\"Principal is null\")) {\n        // verify jcifs DC/domain config and service account before surfacing to user\n        LOGGER.error(\"SPNEGO token processing failed; check JCIFS/Kerberos config\");\n    }\n    throw e;\n}","preventionTips":["Keep setspn registrations in sync with the CAS URL","Synchronize clocks with the KDC (within 5 minutes)","Store the service account password/keytab securely and test after rotation","Enable jcifs debug logging in staging"],"tags":["spnego","kerberos","jcifs","authentication"],"backgroundTag":"authentication-required","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}