quarkusio/quarkus · error · IllegalStateException
Principal is null but anonymous status is false
Error message
Principal is null but anonymous status is false
What it means
QuarkusSecurityIdentity.Builder.build() validates that an identity is coherent: every identity must either have a non-null Principal or be explicitly marked anonymous. If principal==null and anonymous==false the identity would represent an authenticated user with no name, so the builder refuses to construct it. This is a programming/configuration bug in whatever code assembled the identity.
Source
Thrown at extensions/security/runtime/src/main/java/io/quarkus/security/runtime/QuarkusSecurityIdentity.java:312
}
/**
* Sets an anonymous identity status.
*
* @param anonymous the anonymous status
* @return This builder
*/
public Builder setAnonymous(boolean anonymous) {
if (built) {
throw new IllegalStateException();
}
this.anonymous = anonymous;
return this;
}
public QuarkusSecurityIdentity build() {
if (principal == null && !anonymous) {
throw new IllegalStateException("Principal is null but anonymous status is false");
}
addPossesedPermissionsChecker();
built = true;
return new QuarkusSecurityIdentity(this);
}
private void addPossesedPermissionsChecker() {
if (!permissions.isEmpty()) {
addPermissionChecker(
new Function<Permission, Uni<Boolean>>() {
@Override
public Uni<Boolean> apply(Permission requiredPermission) {
for (Permission possessedPermission : permissions) {
if (possessedPermission.implies(requiredPermission)) {
return Uni.createFrom().item(true);View on GitHub (pinned to e1c734241f)
Solutions
- Set a Principal on the builder: builder.setPrincipal(new QuarkusPrincipal(username)) before build().
- If the identity genuinely has no user, call builder.setAnonymous(true) before build().
- When rebuilding an existing identity in an augmentor, copy the principal: builder.setPrincipal(identity.getPrincipal()).
- Audit custom IdentityProvider/Augmentor code paths that construct identities for the missing branch.
- Add a test that builds the identity your provider produces so build() validation runs in CI.
Example fix
// before
QuarkusSecurityIdentity identity = QuarkusSecurityIdentity.builder()
.addRole("user")
.build(); // IllegalStateException
// after
QuarkusSecurityIdentity identity = QuarkusSecurityIdentity.builder()
.setPrincipal(new QuarkusPrincipal(tokenSubject))
.addRole("user")
.build(); Defensive patterns
Strategy: validation
Validate before calling
var builder = QuarkusSecurityIdentity.builder();
if (principal == null && !anonymousFlag) {
throw new IllegalStateException("Identity must set a Principal or be anonymous");
} Type guard
boolean isValidIdentity(QuarkusSecurityIdentity.Builder b, Principal p, boolean anonymous) {
return p != null || anonymous;
} Prevention
- Always call setPrincipal() for authenticated identities
- Call setAnonymous(true) for unauthenticated identities
- In augmentors, copy identity.getPrincipal() into the new builder
- Unit-test identity construction for every custom provider
When it happens
Trigger: Calling QuarkusSecurityIdentity.builder().build() (directly or via a custom IdentityProvider / SecurityIdentityAugmentor) without calling setPrincipal(...) and without calling setAnonymous(true).
Common situations: A custom IdentityProvider that authenticates tokens but forgets to set a Principal; an augmentor that adds roles to an identity but rebuilds it without copying the principal; tests constructing identities by hand.
Related errors
- New SecurityIdentity principal name '%s' is different than p
- Only SecurityIdentity attached to a WebSocket server connect
- No producers for required item %s, step builder used: %s
- cycle detection failure report (dynamic CycleBuildException
- Build step '%s' does not produce any build item and thus wil
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b3ea0b7745da5713.
Report an issue: GitHub.