quarkusio/quarkus · error · IllegalStateException

Cannot transform exception ${exception}

Error message

Cannot transform exception ${exception}

What it means

DefaultAuthExceptionHandlerProvider maps known Quarkus security exceptions (AuthenticationFailedException -> UNAUTHENTICATED, ForbiddenException / AuthorizationDeniedException-style failures -> PERMISSION_DENIED) to gRPC statuses. If the exception passed to transformToStatusException is none of the recognized types, it throws this IllegalStateException wrapping the original exception.

Source

Thrown at extensions/grpc/runtime/src/main/java/io/quarkus/grpc/auth/DefaultAuthExceptionHandlerProvider.java:56

    public boolean handlesException(Throwable failure) {
        return failure instanceof AuthenticationException || failure instanceof SecurityException;
    }

    static Status transformToStatusException(boolean addExceptionMessage, Throwable exception) {
        if (exception instanceof AuthenticationException) {
            if (addExceptionMessage) {
                return Status.UNAUTHENTICATED.withDescription(exception.getMessage());
            } else {
                return Status.UNAUTHENTICATED;
            }
        } else if (exception instanceof SecurityException) {
            if (addExceptionMessage) {
                return Status.PERMISSION_DENIED.withDescription(exception.getMessage());
            } else {
                return Status.PERMISSION_DENIED;
            }
        } else {
            throw new IllegalStateException("Cannot transform exception " + exception, exception);
        }
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Register a custom AuthExceptionHandlerProvider bean that handles your exception type and overrides handlesException() + transformToStatusException() to map it to a StatusException.
  2. Unwrap/rethrow the actual Quarkus security exception (AuthenticationFailedException / ForbiddenException) from your auth code instead of a custom wrapper.
  3. Log the cause (the original exception is attached) to identify which exception type leaks through, then add mapping for it.
  4. Check Quarkus version upgrade notes for changed security exception hierarchy and align your handlers.

Example fix

// before: app code throws
class NotLoggedInException extends RuntimeException {}
// after: throw a mapped type, or add a provider
@ApplicationScoped
class MyProvider implements AuthExceptionHandlerProvider {
  public boolean handlesException(Throwable t) { return t instanceof NotLoggedInException; }
  public StatusException transformToStatusException(Throwable t) {
    return Status.UNAUTHENTICATED.withDescription("Not logged in").asException();
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure thrown auth exceptions are of a mapped type
if (!(ex instanceof AuthenticationFailedException) && !(ex instanceof ForbiddenException)) {
    throw new IllegalStateException("Exception type not mapped by DefaultAuthExceptionHandlerProvider: " + ex.getClass());
}

Type guard

boolean isMappedSecurityException(Throwable t) {
  return t instanceof AuthenticationFailedException || t instanceof ForbiddenException;
}

Try / catch

try {
    status = provider.transformToStatusException(exception);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Cannot transform exception")) {
        // map the unsupported exception yourself or register a custom provider
        status = Status.INTERNAL.withCause(exception).asException();
    } else throw e;
}

Prevention

When it happens

Trigger: A gRPC request fails with a security-related exception that is not an AuthenticationFailedException, ForbiddenException, or other type mapped by DefaultAuthExceptionHandlerProvider, while the provider's handles()/handlesException() accepted it (e.g. a custom RuntimeException thrown from a security check).

Common situations: Custom security mechanisms or identity providers throwing custom exceptions that Quarkus gRPC auth doesn't recognize; upgrading Quarkus where a previously mapped exception type changed; wrapping security exceptions in application exceptions so the type check fails.

Related errors


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