spring-projects/spring-boot · error · MojoFailureException

Could not invoke shutdown operation

Error message

Could not invoke shutdown operation

What it means

Catch-all Exception block in doWaitForSpringApplication. IMPORTANT: the message ('Could not invoke shutdown operation') is misleading -- this code path protects the readiness POLL loop (execute on isReady), not shutdown. Any non-ReflectionException escaping the retry loop is wrapped as MojoFailureException with this message.

Solutions

  1. Inspect the wrapped cause (the real exception class) rather than trusting the message text
  2. Re-run with -X for verbose JMX diagnostics
  3. Verify the application isn't throwing during context refresh / ready evaluation
Defensive patterns

Strategy: try-catch

Try / catch

try { doWaitForSpringApplication(connection); } catch (MojoFailureException ex) { /* message says 'shutdown' but real cause is readiness */ log.error("Readiness poll failed (message is misleading): {}", ex.getCause()); throw ex; }

Prevention

When it happens

Trigger: Any exception other than ReflectionException escaping execute(wait, maxAttempts, isReady) during the readiness poll (e.g. MBeanException, RuntimeException from the isReady callable).

Common situations: Application threw during the ready check; JMX errors during polling that are not reflection failures; the message misleads users toward shutdown when the real cause is readiness.

Related errors


AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11). Data as JSON: /api/errors/fb01f376510760ab. Report an issue: GitHub.

Appendix: source

Thrown at build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java:186

					+ ". Please make sure that no other process is using that port", ex);
		}
		catch (Exception ex) {
			throw new MojoExecutionException("Failed to connect to MBean server at port " + this.jmxPort, ex);
		}
	}

	private void doWaitForSpringApplication(MBeanServerConnection connection)
			throws MojoExecutionException, MojoFailureException {
		final SpringApplicationAdminClient client = new SpringApplicationAdminClient(connection, this.jmxName);
		try {
			Callable<@Nullable Boolean> isReady = () -> (client.isReady() ? true : null);
			execute(this.wait, this.maxAttempts, isReady);
		}
		catch (ReflectionException ex) {
			throw new MojoExecutionException("Unable to retrieve 'ready' attribute", ex.getCause());
		}
		catch (Exception ex) {
			throw new MojoFailureException("Could not invoke shutdown operation", ex);
		}
	}

	/**
	 * Execute a task, retrying it on failure.
	 * @param <T> the result type
	 * @param wait the wait time
	 * @param maxAttempts the maximum number of attempts
	 * @param callback the task to execute (possibly multiple times). The callback should
	 * return {@code null} to indicate that another attempt should be made
	 * @return the result
	 * @throws Exception in case of execution errors
	 */
	public <T> T execute(long wait, int maxAttempts, Callable<@Nullable T> callback) throws Exception {
		getLog().debug("Waiting for spring application to start...");
		for (int i = 0; i < maxAttempts; i++) {
			T result = callback.call();
			if (result != null) {

View on GitHub (pinned to 270dfe353f)