spring-projects/spring-boot · error · MojoExecutionException

Spring application did not start before the configured…

Error message

Spring application did not start before the configured timeout ({}ms)

What it means

After exhausting all maxAttempts retries of isReady() (each returning null/false), the plugin gives up and reports the configured budget as wait*maxAttempts ms. The application launched a JVM but never reached readiness within the configured window.

Solutions

  1. Increase <wait> and/or <maxAttempts> to exceed the worst-case startup time
  2. Profile and optimize startup (lazy init, narrower component scan, fewer auto-configurations)
  3. Pre-warm slow dependencies (DB pool, schema migration) before invoking spring-boot:run

Example fix

<!-- before -->
<maxAttempts>20</maxAttempts>
<!-- after -->
<maxAttempts>120</maxAttempts>
Defensive patterns

Strategy: validation

Validate before calling

// Estimate startup budget before running
long budgetMs = (long) wait * maxAttempts;
if (budgetMs < expectedWorstCaseStartupMs) { /* raise wait or maxAttempts */ }

Try / catch

try { waitForSpringApplication(); } catch (MojoExecutionException ex) { log.error("App did not become ready in {}ms; increase <wait>/<maxAttempts> or optimize startup", wait*maxAttempts); throw ex; }

Prevention

When it happens

Trigger: Application startup slower than wait*maxAttempts ms: long context init, slow DB migrations, blocking remote dependency waits.

Common situations: Cold start with many beans; slow external config server; profiling/debug agent slowing JVM; large classpath scanning.

Understand the failure class

Related errors


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

Appendix: source

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

		getLog().debug("Waiting for spring application to start...");
		for (int i = 0; i < maxAttempts; i++) {
			T result = callback.call();
			if (result != null) {
				return result;
			}
			String message = "Spring application is not ready yet, waiting " + wait + "ms (attempt " + (i + 1) + ")";
			getLog().debug(message);
			synchronized (this.lock) {
				try {
					this.lock.wait(wait);
				}
				catch (InterruptedException ex) {
					Thread.currentThread().interrupt();
					throw new IllegalStateException("Interrupted while waiting for Spring Boot app to start.");
				}
			}
		}
		throw new MojoExecutionException(
				"Spring application did not start before the configured timeout (" + (wait * maxAttempts) + "ms");
	}

	@Override
	protected TestClasspath testClasspath() {
		if (this.resolvedTestClasspath == null) {
			if (this.useTestClasspath != null) {
				getLog().warn("useTestClasspath is deprecated, use testClasspath instead.");
				this.resolvedTestClasspath = (this.useTestClasspath) ? TestClasspath.DEPENDENCIES : TestClasspath.OFF;
			}
			else {
				this.resolvedTestClasspath = TestClasspath.valueOf(this.testClasspath.toUpperCase(Locale.ROOT));
			}
		}
		return this.resolvedTestClasspath;
	}

	private class CreateJmxConnector implements Callable<@Nullable JMXConnector> {

View on GitHub (pinned to 270dfe353f)