Introduction
Spring Boot application startup failures occur when the ApplicationContext cannot initialize due to bean creation errors, misconfiguration, or external dependency failures. The application fails fast during the startup phase, never reaching a running state. Errors manifest as ApplicationContextException, BeanCreationException, BinderException, or specific cause exceptions like CommunicationsException for database failures. Startup failures are particularly challenging because the application cannot serve health checks or accept traffic, and error messages may be nested several levels deep in the stack trace.
Symptoms
- Application exits immediately after starting with exit code 1
- Logs show
APPLICATION_FAILEDwith stack trace BeanCreationExceptionorApplicationContextExceptionin logs- Startup failure after
Finished SpringApplication.run - Kubernetes pod shows
CrashLoopBackOffwith application logs showing startup error - Issue appears after deploy with configuration changes, dependency updates, or environment changes
Common Causes
@Beanmethod throws exception during initialization- Required configuration property missing or invalid type
- Database connection failed (wrong URL, credentials, or database down)
- Port already in use (another process or duplicate application)
- Auto-configuration conflict (multiple implementations on classpath)
- Circular dependency between beans
- Classpath issues (missing dependency, version conflict)
- Profile-specific configuration not activated correctly
Step-by-Step Fix
### 1. Analyze startup failure logs
Extract the root cause from stack trace:
```bash # Spring Boot startup logs show failure analysis # Look for this section:
*************************** APPLICATION FAILED TO START ***************************
Description: An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.boot.SpringApplication.run(SpringApplication.java:XXX)
Action: Update your dependencies to ensure compatibility
# Or for bean creation failures:
Description: Parameter 0 of constructor in com.example.MyService required a bean of type 'com.example.MyRepository' that could not be found.
Action: Consider defining a bean of type 'com.example.MyRepository' in your configuration. ```
Enable debug logging:
```yaml # application.yml logging: level: root: WARN com.example: DEBUG org.springframework: DEBUG org.springframework.boot.autoconfigure: DEBUG
# Or via environment variable export DEBUG=true java -jar myapp.jar
# Or command line java -jar myapp.jar --debug ```
Analyze condition evaluation report:
```bash # Spring Boot prints condition evaluation report with --debug # Look for:
CONDITIONS EVALUATION REPORT ============================
Positive matches: -----------------
DataSourceAutoConfiguration matched: - @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.core.JdbcTemplate' (OnClassCondition) - @ConditionalOnProperty spring.datasource.url (OnPropertyCondition)
Negative matches: -----------------
RedisAutoConfiguration did not match: - @ConditionalOnClass did not find required class 'org.springframework.data.redis.RedisConnection' (OnClassCondition)
# This shows which auto-configurations were applied and why others were skipped ```
### 2. Check for port binding conflicts
Port already in use is a common failure:
``` *************************** APPLICATION FAILED TO START ***************************
Description: Web server failed to start. Port 8080 was already in use.
Action: Identify and stop the process currently listening on port 8080 or configure this application to listen on another port. ```
Check port usage:
```bash # Linux/Mac lsof -i :8080 netstat -tlnp | grep 8080 ss -tlnp | grep 8080
# Windows netstat -ano | findstr :8080
# Kill process on port fuser -k 8080/tcp # Linux kill -9 $(lsof -t -i:8080) # Mac/Linux ```
Configure different port:
```yaml # application.yml server: port: 8081 # Use different port
# Or random available port (for tests) server: port: 0 ```
Programmatic port selection:
java
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MyApplication.class)
.properties("server.port=8081")
.run(args);
}
}
### 3. Check database connectivity
Database connection failures are common:
``` *************************** APPLICATION FAILED TO START ***************************
Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class ```
Fix DataSource configuration:
yaml
# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: ${DB_USERNAME:postgres}
password: ${DB_PASSWORD:secret}
driver-class-name: org.postgresql.Driver
hikari:
connection-timeout: 30000
maximum-pool-size: 10
Test connection before Spring starts:
```java @Configuration public class DatabaseHealthCheck {
@Bean public DataSource dataSource(DataSourceProperties properties) { HikariConfig config = new HikariConfig(); config.setJdbcUrl(properties.getUrl()); config.setUsername(properties.getUsername()); config.setPassword(properties.getPassword());
// Test connection during startup try (HikariDataSource ds = new HikariDataSource(config); Connection conn = ds.getConnection()) { // Connection successful System.out.println("Database connection test: OK"); } catch (SQLException e) { throw new BeanCreationException( "Database connection failed: " + e.getMessage(), e); }
return new HikariDataSource(config); } } ```
Check database availability:
```bash # Test database connectivity nc -zv localhost 5432 psql -h localhost -U postgres -d mydb -c "SELECT 1"
# Check if database is accepting connections # MySQL mysql -h localhost -u root -p -e "SELECT 1"
# For remote database telnet db.example.com 5432 ```
### 4. Check configuration property binding
Invalid configuration causes startup failure:
``` *************************** APPLICATION FAILED TO START ***************************
Description: Binding to target com.example.MyProperties@xxxx failed:
Property: myapp.max-connections Value: "not-a-number" Reason: Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' ```
Fix configuration:
yaml
# application.yml
myapp:
max-connections: 100 # Must be integer, not string
timeout: 30s # Use Duration format
enabled: true # Boolean
features: # List
- feature1
- feature2
Configuration class:
```java @Configuration @ConfigurationProperties(prefix = "myapp") @Validated public class MyAppProperties {
@NotNull @Min(1) @Max(1000) private Integer maxConnections = 100;
@NotNull private Duration timeout = Duration.ofSeconds(30);
private boolean enabled = true;
private List<String> features = new ArrayList<>();
// Getters and setters } ```
Validate configuration at startup:
```java @Component public class ConfigurationValidator implements ApplicationRunner {
private final MyAppProperties properties;
public ConfigurationValidator(MyAppProperties properties) { this.properties = properties; }
@Override public void run(ApplicationArguments args) { if (properties.getMaxConnections() > 500) { throw new BeanValidationException( "max-connections cannot exceed 500"); } System.out.println("Configuration validated successfully"); } } ```
### 5. Check bean creation and circular dependencies
Circular dependencies prevent bean creation:
``` *************************** APPLICATION FAILED TO START ***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
serviceA defined in class path resource [com/example/ServiceA.class] ┌─────┐ ↓ ↑ serviceB defined in class path resource [com/example/ServiceB.class] ┌─────┐ ↓ ↑ serviceC defined in class path resource [com/example/ServiceC.class] └─────┘ ```
Fix circular dependency:
```java // WRONG: Circular dependency @Service public class ServiceA { private final ServiceB serviceB;
public ServiceA(ServiceB serviceB) { this.serviceB = serviceB; } }
@Service public class ServiceB { private final ServiceA serviceA; // Creates cycle
public ServiceB(ServiceA serviceA) { this.serviceA = serviceA; } }
// CORRECT: Break cycle with interface or @Lazy @Service public class ServiceA { private final ServiceB serviceB;
public ServiceA(ServiceB serviceB) { this.serviceB = serviceB; } }
@Service public class ServiceB { private final ObjectProvider<ServiceA> serviceAProvider; // Lazy injection
public ServiceB(ObjectProvider<ServiceA> serviceAProvider) { this.serviceAProvider = serviceAProvider; }
public void doSomething() { ServiceA serviceA = serviceAProvider.getIfAvailable(); serviceA.doWork(); } } ```
Or use @Lazy:
```java @Service public class ServiceB { private final ServiceA serviceA;
public ServiceB(@Lazy ServiceA serviceA) { this.serviceA = serviceA; } } ```
### 6. Check auto-configuration conflicts
Multiple auto-configurations may conflict:
``` *************************** APPLICATION FAILED TO START ***************************
Description:
The following methods, when combined, create an ambiguous bean definition:
@Bean method MyConfig.dataSource() @Bean method AutoConfig.dataSource() ```
Exclude conflicting auto-configuration:
java
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
RedisAutoConfiguration.class
})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Or via properties:
yaml
# application.yml
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
Define explicit beans:
```java @Configuration public class MyConfig {
@Bean @Primary // Mark as primary if multiple exist public DataSource dataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb"); return new HikariDataSource(config); } } ```
### 7. Check classpath and dependency conflicts
Missing or conflicting dependencies:
``` *************************** APPLICATION FAILED TO START ***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
com.example.MyService.init(MyService.java:42)
The following method did not exist:
'void com.google.common.collect.ImmutableList.of(java.lang.Object)'
The method's class, com.google.common.collect.ImmutableList, is available from the following locations:
jar:file:/.../guava-20.0.jar!/com/google/common/collect/ImmutableList.class
The method's class version (52.0) is older than the required version (55.0). ```
Fix dependency conflicts:
```xml <!-- pom.xml --> <dependencies> <!-- Force specific version --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>32.0.0-jre</version> </dependency>
<!-- Exclude transitive dependency --> <dependency> <groupId>org.example</groupId> <artifactId>some-lib</artifactId> <exclusions> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
<!-- Use dependency management --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.2.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ```
Check for dependency conflicts:
```bash # Maven: show dependency tree mvn dependency:tree
# Find conflicting versions mvn dependency:tree -Dverbose -Dincludes=com.google.guava
# Gradle: show dependencies ./gradlew dependencies
# Find duplicate classes mvn org.apache.maven.plugins:maven-enforcer-plugin:enforce -Drules=requireUpperBoundDeps ```
### 8. Check profile-specific configuration
Wrong profile activation causes failures:
```bash # Check active profiles java -jar myapp.jar --spring.profiles.active=dev
# Or via environment export SPRING_PROFILES_ACTIVE=dev java -jar myapp.jar
# Or in application.yml spring: profiles: active: dev ```
Profile-specific configuration:
```yaml # application.yml (common) spring: datasource: url: ${DB_URL}
# application-dev.yml spring: datasource: url: jdbc:postgresql://localhost:5432/devdb username: dev password: dev
# application-prod.yml spring: datasource: url: jdbc:postgresql://prod-db:5432/proddb username: ${PROD_DB_USER} password: ${PROD_DB_PASS} ```
Validate profile at startup:
```java @Component @Profile("dev") public class DevProfileChecker implements ApplicationRunner {
@Override public void run(ApplicationArguments args) { System.out.println("Running with 'dev' profile"); // Dev-specific initialization } } ```
### 9. Implement graceful startup failure handling
Custom failure analyzer:
```java public class DatabaseConnectionFailureAnalyzer implements FailureAnalyzer {
@Override public FailureAnalysis analyze(Throwable rootFailure) { if (rootFailure instanceof CannotCreateTransactionException) { Throwable cause = rootFailure.getCause(); if (cause instanceof SQLException) { return new FailureAnalysis( "Database connection failed", "Check database URL, credentials, and network connectivity", cause); } } return null; // Let other analyzers handle } } ```
Register analyzer:
# META-INF/spring.factories
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.DatabaseConnectionFailureAnalyzer
Startup health check:
```java @Component public class StartupHealthChecker implements ApplicationRunner {
private final List<HealthChecker> checkers;
public StartupHealthChecker(List<HealthChecker> checkers) { this.checkers = checkers; }
@Override public void run(ApplicationArguments args) { for (HealthChecker checker : checkers) { try { checker.check(); System.out.println(checker.name() + ": OK"); } catch (Exception e) { System.err.println(checker.name() + ": FAILED - " + e.getMessage()); throw new BeanCreationException( "Startup health check failed: " + checker.name(), e); } } } }
interface HealthChecker { String name(); void check() throws Exception; } ```
### 10. Enable startup failure analysis
Spring Boot's failure analysis provides actionable messages:
```java // Custom exception with failure analysis public class ConfigurationException extends RuntimeException {
private final String action;
public ConfigurationException(String description, String action) { super(description); this.action = action; }
public String getAction() { return action; } }
// Throw with actionable message throw new ConfigurationException( "Database URL not configured", "Set SPRING_DATASOURCE_URL environment variable or add 'spring.datasource.url' to application.yml" ); ```
Prevention
- Use
@ConfigurationPropertieswith validation for type-safe configuration - Implement startup health checks for all external dependencies
- Use Spring Boot Actuator for startup diagnostics
- Enable debug logging in development environments
- Test configuration changes in staging before production
- Use profile-specific configuration files consistently
- Document required environment variables and configuration
Related Errors
- **ApplicationContextException**: Parent exception for context failures
- **BeanCreationException**: Specific bean failed to create
- **BinderException**: Configuration property binding failed
- **PortInUseException**: Server port already bound