quarkusio/quarkus · error · RuntimeException

Failed to get user principal

Error message

Failed to get user principal

What it means

Sentinel RuntimeException thrown by RootResource.posts() when SecurityContext.getUserPrincipal().getName() is null on the POST path. It indicates the request was not associated with an authenticated principal despite the endpoint expecting one under Elytron security in RESTEasy Reactive.

Source

Thrown at integration-tests/elytron-resteasy-reactive/src/main/java/io/quarkus/it/resteasy/reactive/elytron/RootResource.java:33

import jakarta.ws.rs.core.SecurityContext;

import io.quarkus.security.Authenticated;
import io.quarkus.security.PermissionsAllowed;
import io.quarkus.security.identity.SecurityIdentity;

@Path("/")
public class RootResource {
    @Inject
    SecurityIdentity identity;

    @POST
    @Consumes(MediaType.TEXT_PLAIN)
    public String posts(String data, @Context SecurityContext sec) {
        if (data == null) {
            throw new RuntimeException("No post data");
        }
        if (sec.getUserPrincipal().getName() == null) {
            throw new RuntimeException("Failed to get user principal");
        }
        return "post success";
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String approval(@Context SecurityContext sec) {
        if (sec.getUserPrincipal().getName() == null) {
            throw new RuntimeException("Failed to get user principal");
        }
        return "get success";
    }

    @GET
    @Path("/secure")
    @Authenticated
    public String getSecure() {
        return "secure";

View on GitHub (pinned to e1c734241f)

Solutions

  1. Attach valid Basic Auth credentials to the POST request
  2. Verify the Elytron reactive security extension is configured (realm, users, roles in application.properties)
  3. Confirm the POST path is not accidentally exempted from authentication by a permission/policy rule
  4. Check identity propagation from the HTTP layer into the JAX-RS SecurityContext

Example fix

// before
curl -X POST http://localhost:8080/api -d 'hello'
// after
curl -u admin:admin -X POST http://localhost:8080/api -d 'hello'
Defensive patterns

Strategy: validation

Validate before calling

Principal p = sec.getUserPrincipal();
if (p == null || p.getName() == null) {
    throw new NotAuthorizedException("No authenticated principal");
}
if (data == null || data.isBlank()) {
    throw new BadRequestException("Body required");
}

Type guard

boolean authenticatedWithBody(String data, SecurityContext sec) {
    return hasBody(data) && sec != null && sec.getUserPrincipal() != null && sec.getUserPrincipal().getName() != null;
}

Try / catch

try {
    return handle(data, sec);
} catch (RuntimeException e) {
    throw new InternalServerErrorException("POST handling failed", e);
}

Prevention

When it happens

Trigger: POST with text body but no valid authentication, so sec.getUserPrincipal() yields a principal with null name (or anonymous identity).

Common situations: Missing Authorization header; wrong credentials; security not activated for the reactive runtime; test client forgetting basic auth after switching from classic RESTEasy to reactive.

Related errors


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