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

  1. Set a Principal on the builder: builder.setPrincipal(new QuarkusPrincipal(username)) before build().
  2. If the identity genuinely has no user, call builder.setAnonymous(true) before build().
  3. When rebuilding an existing identity in an augmentor, copy the principal: builder.setPrincipal(identity.getPrincipal()).
  4. Audit custom IdentityProvider/Augmentor code paths that construct identities for the missing branch.
  5. 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

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


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/b3ea0b7745da5713. Report an issue: GitHub.