Skip to content

SPIFFE Client assertion throws a NullPointerException if no client is found #46669

@ryanemerson

Description

@ryanemerson

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

token-exchange

Describe the bug

The SpiffeClientAssertionStrategy#lookup throws a NullPointerException if the alternative lookup of the Client fails to find a client.

Version

26.6.0-SNAPSHOT

Regression

  • The issue is a regression

Expected behavior

The SpiffeClientAssertionStrategy#lookup method should handle a failed lookup gracefully and just return null.

Actual behavior

A NullPointerException is thrown:

2026-02-27 11:09:00,062 WARN  [org.keycloak.authentication.authenticators.client.FederatedJWTClientAuthenticator] (executor-thread-1) Authentication failed: java.lang.NullPointerException: Cannot invoke "org.keycloak.models.ClientModel.getAttribute(String)" because "client" is null
	at org.keycloak.broker.spiffe.SpiffeClientAssertionStrategy.lookup(SpiffeClientAssertionStrategy.java:31)
	at org.keycloak.authentication.authenticators.client.FederatedJWTClientAuthenticator.authenticateClient(FederatedJWTClientAuthenticator.java:99)
	at org.keycloak.authentication.ClientAuthenticationFlow.processFlow(ClientAuthenticationFlow.java:74)
	at org.keycloak.authentication.AuthenticationProcessor.authenticateClient(AuthenticationProcessor.java:965)
	at org.keycloak.protocol.oidc.utils.AuthorizeClientUtil.authorizeClient(AuthorizeClientUtil.java:51)
	at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.checkClient(TokenEndpoint.java:180)
	at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.processGrantRequest(TokenEndpoint.java:136)
	at org.keycloak.protocol.oidc.endpoints.TokenEndpoint$quarkusrestinvoker$processGrantRequest_3903cccf0670c489ab77dc2ba1ba757573ec6d78.invoke(Unknown Source)
	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
	at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:190)
	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:666)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2651)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2630)
	at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1622)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1589)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:1474)

How to Reproduce?

Create a client with a jwt.credential.sub that does not match the SPIFFE ID encoded as part of the client_assertion JWT.

Anything else?

No response

Metadata

Metadata

Assignees

Type

No fields configured for bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions