Axon 4.0 custom command gateway with Axon Server didn't throw the declared checked exception

Hi all,

I created a custom command gateway connected to the Axon Server as follows:


public interface MyCommandGateway extends MessageDispatchInterceptorSupport<CommandMessage<?>> {
CompletableFuture send(Object command) throws CommandHandlingException;

void sendAndWait(Object command) throws CommandHandlingException;

public class CommandHandlingException extends Exception {
public CommandHandlingException(String msg) {

public MyCommandGateway myCommandGateway() {
CommandGatewayFactory factory = CommandGatewayFactory.builder().commandBus(commandBus).build(); // The commandBus is AxonServerCommandBus
return factory.createGateway(MyCommandGateway.class);


According to the document,

Any declared checked exception will be thrown if the command handler (or an interceptor) threw an exception of that type. If a checked exception is thrown that has not been declared, it is wrapped in a CommandExecutionException, which is a RuntimeException

when my command handler throws the CommandHandlingException, the above sendAndWait method should also throws this checked exception.
However, in fact, I got a AxonServerRemoteCommandHandlingException which is a RuntimeException.

So How can I get the checked exception when my command handler throws it?

My command gateway and the command handler run on two different service instances.


we currently have a ticket in our backlog to streamline exception handling across distributed and local implementation of buses. The issue is that the approach we have taken for the local command buses (such as the SimpleCommandBus), from which the behavior on the CommandGateway is also derived, is not suitable for distributed environments.
Exceptions are not transported from server to client, but instead are reported by their class name and message. The AxonServerRemoteCommandHandlingException currently has a getExceptionDescriptions() method that describes the (remote) causes of the exception.

In the next version of Axon, we plan to deal with this more elegantly and consistently across implementations.