junit-team/junit5 · error · JUnitException

Scheduled executor could not be stopped in an orderly manner

Error message

Scheduled executor could not be stopped in an orderly manner

What it means

Thrown by TimeoutInvocationFactory.ExecutorResource.close() when the internal 'junit-jupiter-timeout-watcher' single-thread ScheduledExecutorService does not terminate within 5 seconds of calling shutdown(). After the grace period, shutdownNow() is called and this JUnitException is raised. This executor is used for same-thread timeout enforcement (ThreadMode.SAME_THREAD) to schedule the timeout watcher task.

Source

Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutInvocationFactory.java:71

	abstract static class ExecutorResource implements Store.CloseableResource, AutoCloseable {

		private final ScheduledExecutorService executor;

		ExecutorResource(ScheduledExecutorService executor) {
			this.executor = executor;
		}

		ScheduledExecutorService get() {
			return executor;
		}

		@Override
		public void close() throws Exception {
			executor.shutdown();
			boolean terminated = executor.awaitTermination(5, TimeUnit.SECONDS);
			if (!terminated) {
				executor.shutdownNow();
				throw new JUnitException("Scheduled executor could not be stopped in an orderly manner");
			}
		}
	}

	@SuppressWarnings("try")
	static class SingleThreadExecutorResource extends ExecutorResource {

		@SuppressWarnings({ "unused", "ThreadPriorityCheck" })
		SingleThreadExecutorResource() {
			super(Executors.newSingleThreadScheduledExecutor(runnable -> {
				Thread thread = new Thread(runnable, "junit-jupiter-timeout-watcher");
				thread.setPriority(Thread.MAX_PRIORITY);
				return thread;
			}));
		}
	}

}

View on GitHub (pinned to 956246301e)

Solutions

  1. Rerun the test in isolation to rule out transient CI load
  2. Use ThreadMode.SEPARATE_THREAD (@Timeout(threadMode = ThreadMode.SEPARATE_THREAD)) which does not use this same-thread executor
  3. Ensure the test JVM has adequate CPU/memory resources
  4. Check for tests that hang in uninterruptible blocking operations (e.g., native I/O, infinite loops)
Defensive patterns

Strategy: try-catch

Try / catch

// This error occurs during context teardown, not in user code.
// Mitigate by using SEPARATE_THREAD mode to avoid the same-thread executor:
@Timeout(value = 5, unit = TimeUnit.SECONDS, threadMode = ThreadMode.SEPARATE_THREAD)

Prevention

When it happens

Trigger: The executor's scheduled task (the timeout watcher) does not complete within 5 seconds of JUnit shutting down the test context. This can happen if the JVM is under heavy load, if the watched thread is stuck in an uninterruptible operation, or if the test harness is being forcefully torn down.

Common situations: Running in a heavily loaded CI environment, a test that hangs in a way that blocks the watcher thread, OOM or resource exhaustion during teardown, or running on a very slow/containerized machine where thread scheduling is delayed beyond 5 seconds.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/7ab6a6940b4c62ed.json. Report an issue: GitHub.