spring-projects/spring-security · error · IllegalStateException
ticketValidator must be set
Error message
ticketValidator must be set
What it means
KerberosServiceAuthenticationProvider.authenticate validates a Kerberos service ticket using a TicketValidator. It throws IllegalStateException when `ticketValidator` was never set, meaning the provider is not configured for SPNEGO/service-ticket authentication.
Source
Thrown at kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/authentication/KerberosServiceAuthenticationProvider.java:71
* @see UserDetailsService
*/
public class KerberosServiceAuthenticationProvider implements AuthenticationProvider, InitializingBean {
private static final Log LOG = LogFactory.getLog(KerberosServiceAuthenticationProvider.class);
private @Nullable KerberosTicketValidator ticketValidator;
private @Nullable UserDetailsService userDetailsService;
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
KerberosServiceRequestToken auth = (KerberosServiceRequestToken) authentication;
byte[] token = auth.getToken();
LOG.debug("Try to validate Kerberos Token");
if (this.ticketValidator == null) {
throw new IllegalStateException("ticketValidator must be set");
}
if (this.userDetailsService == null) {
throw new IllegalStateException("userDetailsService must be set");
}
KerberosTicketValidation ticketValidation = this.ticketValidator.validateTicket(token);
LOG.debug("Successfully validated " + ticketValidation.username());
UserDetails userDetails = this.userDetailsService.loadUserByUsername(ticketValidation.username());
this.userDetailsChecker.check(userDetails);
additionalAuthenticationChecks(userDetails, auth);
KerberosServiceRequestToken responseAuth = new KerberosServiceRequestToken(userDetails, ticketValidation,
userDetails.getAuthorities(), token);
responseAuth.setDetails(authentication.getDetails());
return responseAuth;
}
@Override
public boolean supports(Class<? extends Object> auth) {
return KerberosServiceRequestToken.class.isAssignableFrom(auth);View on GitHub (pinned to 96852e8860)
Solutions
- Call setTicketValidator(...) with a configured KerberosTicketValidator (e.g. SunJaasKerberosTicketValidator with servicePrincipal and keytabLocation).
- Ensure the ticket validator bean is defined and injected into the provider.
- Verify the keytab file exists and is readable so bean initialization succeeds.
Example fix
// before
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setUserDetailsService(uds);
// after
SunJaasKerberosTicketValidator validator = new SunJaasKerberosTicketValidator();
validator.setServicePrincipal("HTTP/host@REALM");
validator.setKeytabLocation("/etc/security/http.keytab");
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(validator);
provider.setUserDetailsService(uds); Defensive patterns
Strategy: validation
Validate before calling
if (provider instanceof KerberosServiceAuthenticationProvider k && k.getTicketValidator() == null) throw new IllegalStateException("ticketValidator not wired");
if (!Files.isReadable(Path.of(keytabLocation))) throw new IllegalStateException("keytab unreadable"); Try / catch
try {
return authenticationManager.authenticate(kerberosToken);
} catch (IllegalStateException e) {
LOG.error("SPNEGO provider misconfigured: {}", e.getMessage());
throw e;
} Prevention
- Wire ticketValidator and userDetailsService in the same bean definition.
- Verify keytab file existence/readability as a startup check.
- Add an SPNEGO round-trip test in the integration suite.
When it happens
Trigger: Placing a KerberosServiceAuthenticationProvider in the AuthenticationManager without calling setTicketValidator, then processing a KerberosServiceRequestToken (SPNEGO header) request.
Common situations: SPNEGO filter wired to a provider whose ticket validator bean (SunJaasKerberosTicketValidator / KerberosTicketValidator) was never injected, or the bean creation failed silently in a non-active profile.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- userDetailsService must be set
- Error running rest call
- kerberosClient must be set
- userDetailsService must be set
- Unauthenticated or no response token
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/58aa60dc6c9e81f5.
Report an issue: GitHub.