Bug Report
Describe the Bug
Currently, during shutdown it's possible to see exceptions like:
[consumer-control-plane] SEVERE 2026-07-03T10:08:48.006670116 StateMachineManager [ProviderContractNegotiationManagerImpl] unrecoverable error
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@763345e2[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@370e4fd9[Wrapped task = org.eclipse.edc.statemachine.StateMachineManager$$Lambda/0x0000734ff9867d80@3331cde0]] rejected from java.util.concurrent.ScheduledThreadPoolExecutor@1985591d[Shutting down, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 837]
at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2081)
at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:841)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:340)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:562)
at java.base/java.util.concurrent.Executors$DelegatedScheduledExecutorService.schedule(Executors.java:871)
at org.eclipse.edc.statemachine.StateMachineManager.scheduleNextIterationIn(StateMachineManager.java:135)
at org.eclipse.edc.statemachine.StateMachineManager.performLogic(StateMachineManager.java:129)
at org.eclipse.edc.statemachine.StateMachineManager.logic(StateMachineManager.java:105)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
these are harmless but they could create confusion
Expected Behavior
not to see exceptions
Observed Behavior
The RejectedExecutionException occurs because the manager’s logic runnable (the state machine loop) tries to schedule its next iteration after stop() has already called executor.shutdown() The race condition is:
logic() starts, checks active.get() (true), proceeds to process state machines.
- Meanwhile,
stop() is called, sets active = false, and calls executor.shutdown().
logic() finishes processing and then calls scheduleNextIterationIn() to schedule itself again.
scheduleNextIterationIn() calls executor.schedule(...) – but the executor is now shutting down, so it throws RejectedExecutionException.
Steps to Reproduce
run e2e tests
Possible Implementation
guard the scheduling call, not the logic one
Bug Report
Describe the Bug
Currently, during shutdown it's possible to see exceptions like:
these are harmless but they could create confusion
Expected Behavior
not to see exceptions
Observed Behavior
The
RejectedExecutionExceptionoccurs because the manager’s logic runnable (the state machine loop) tries to schedule its next iteration afterstop()has already calledexecutor.shutdown()The race condition is:logic()starts, checksactive.get()(true), proceeds to process state machines.stop()is called, setsactive = false, and callsexecutor.shutdown().logic()finishes processing and then callsscheduleNextIterationIn()to schedule itself again.scheduleNextIterationIn()callsexecutor.schedule(...)– but the executor is now shutting down, so it throwsRejectedExecutionException.Steps to Reproduce
run e2e tests
Possible Implementation
guard the scheduling call, not the logic one