{"record":{"id":"c4359a3ea3cc5431","repo":"quarkusio/quarkus","slug":"cannot-transform-exception-exception","errorCode":null,"errorMessage":"Cannot transform exception ${exception}","messagePattern":"Cannot transform exception (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/runtime/src/main/java/io/quarkus/grpc/auth/DefaultAuthExceptionHandlerProvider.java","lineNumber":56,"sourceCode":"    public boolean handlesException(Throwable failure) {\n        return failure instanceof AuthenticationException || failure instanceof SecurityException;\n    }\n\n    static Status transformToStatusException(boolean addExceptionMessage, Throwable exception) {\n        if (exception instanceof AuthenticationException) {\n            if (addExceptionMessage) {\n                return Status.UNAUTHENTICATED.withDescription(exception.getMessage());\n            } else {\n                return Status.UNAUTHENTICATED;\n            }\n        } else if (exception instanceof SecurityException) {\n            if (addExceptionMessage) {\n                return Status.PERMISSION_DENIED.withDescription(exception.getMessage());\n            } else {\n                return Status.PERMISSION_DENIED;\n            }\n        } else {\n            throw new IllegalStateException(\"Cannot transform exception \" + exception, exception);\n        }\n    }\n}\n","sourceCodeStart":38,"sourceCodeEnd":60,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/auth/DefaultAuthExceptionHandlerProvider.java#L38-L60","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Register a custom AuthExceptionHandlerProvider bean that handles your exception type and overrides handlesException() + transformToStatusException() to map it to a StatusException.","Unwrap/rethrow the actual Quarkus security exception (AuthenticationFailedException / ForbiddenException) from your auth code instead of a custom wrapper.","Log the cause (the original exception is attached) to identify which exception type leaks through, then add mapping for it.","Check Quarkus version upgrade notes for changed security exception hierarchy and align your handlers."],"exampleFix":"// before: app code throws\nclass NotLoggedInException extends RuntimeException {}\n// after: throw a mapped type, or add a provider\n@ApplicationScoped\nclass MyProvider implements AuthExceptionHandlerProvider {\n  public boolean handlesException(Throwable t) { return t instanceof NotLoggedInException; }\n  public StatusException transformToStatusException(Throwable t) {\n    return Status.UNAUTHENTICATED.withDescription(\"Not logged in\").asException();\n  }\n}","handlingStrategy":"try-catch","validationCode":"// ensure thrown auth exceptions are of a mapped type\nif (!(ex instanceof AuthenticationFailedException) && !(ex instanceof ForbiddenException)) {\n    throw new IllegalStateException(\"Exception type not mapped by DefaultAuthExceptionHandlerProvider: \" + ex.getClass());\n}","typeGuard":"boolean isMappedSecurityException(Throwable t) {\n  return t instanceof AuthenticationFailedException || t instanceof ForbiddenException;\n}","tryCatchPattern":"try {\n    status = provider.transformToStatusException(exception);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Cannot transform exception\")) {\n        // map the unsupported exception yourself or register a custom provider\n        status = Status.INTERNAL.withCause(exception).asException();\n    } else throw e;\n}","preventionTips":["Throw standard Quarkus security exceptions (AuthenticationFailedException, ForbiddenException) from auth code","Register a custom AuthExceptionHandlerProvider for custom exception types","Don't wrap security exceptions in application-specific wrappers before they reach gRPC handlers","After Quarkus upgrades, re-verify which security exceptions your handlers cover"],"tags":["grpc","quarkus","auth","security","exception-mapping"],"backgroundTag":"unhandled-security-exception","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}