"message unhandled" logged when using Behaviors#transformMessages

I would expect no “message unhandled” messages in the log when using akka.actor.typed.javadsl.Behaviors#transformMessages ?

Actual log message: 09:44:21,458 INFO [LocalActorRef] Message [MyMessage] from Actor[akka://sys@] to Actor[akka://sys#-2054150271] was unhandled. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings ‘akka.log-dead-letters’ and ‘akka.log-dead-letters-during-shutdown’.

I think this is not really related to Behaviors#transformMessages because the log message appears only once, after starting the system. Subsequent message traffic does not generate “unhandled” log messages.

Which Akka version is that. I just verified with one of the tests we have that it is logged as unhandled dead letter.

Akka 2.6.3

That is strange. Then it would good if you can provide an example of how to reproduce it, because that is not what I’m seeing.

This is my utility method:

	public static <W, N extends W> Behavior<W> receiveOnly(
			Class<W> outerMsgClass,
			Class<N> innerMsgClass,
			Function<N, Behavior<N>> onMessage) {

		return transformMessages(outerMsgClass, receiveMessage(onMessage::apply), selector -> {
			return selector.match(innerMsgClass, m -> m);

Message class hierarchy:

class JobProgressUpdated implements JobProgressEvent

Behavior using transformMessages:

	Behavior<JobProgressEvent> jobActivityConfirmation(ActorRef<ConfirmJobActivity> target) {
		return receiveOnly(JobProgressEvent.class, JobProgressUpdated.class, event -> {
			target.tell(new ConfirmJobActivity(event.getJobId()));
			return same();

Equivalent behavior without using transformMessages:

	Behavior<JobProgressEvent> jobActivityConfirmation(ActorRef<ConfirmJobActivity> target) {
		return receive(JobProgressEvent.class)
				.onMessage(JobProgressUpdated.class, event -> {
					target.tell(new ConfirmJobActivity(event.getJobId()));
					return same();
				.onAnyMessage(ev -> same())

Actor factory method (called from parent EventsourcedBehavior (see below)):

	ActorRef jobActivityConfirmer(ActorContext<JobExecutionCommand> ctx) {
		return toClassic(ctx.spawn(jobActivityConfirmation(ctx.getSelf().narrow()), "JobActivityConfirmer-" + anyString(5)));

Creation of parent EventSourced behavior (JobExecution):

	Behavior<JobExecutionCommand> jobExecution(JMS jms) {
		return withTimers(scheduler -> {
			scheduler.startTimerWithFixedDelay(new ExpireOverrunningJobs(), overrunningJobsCheckoutInterval);

			return setup(ctx -> {
				jms.distributedPubSub().subscribe(ProgressTopicName, jobActivityConfirmer(ctx));
				return new JobExecution(jms, ctx);

I can confirm that “message unhandled” is logged only if using Behaviors#transformMessages. It is only logged when I’m performing the initial test (after starting the system). Subsequent tests do not produce “message unhandled” log message.

Note that you can configure how many are logged: https://github.com/akka/akka/blob/master/akka-actor/src/main/resources/reference.conf#L56

I think it’s the same setting for unhanded.
You may also use https://github.com/akka/akka/blob/master/akka-actor/src/main/resources/reference.conf#L66

Thanks. I have applied log-dead-letters = on
and now the unhandled messages are logged every time I perform the test (with transformMessages).