What's Actually Happening
Your Spring Boot application fails to start with an application context initialization error. The Spring container cannot create or wire the required beans, preventing the application from starting. The stack trace shows various bean creation exceptions, dependency injection failures, or configuration problems that block the entire application startup.
This is a critical error because the application cannot serve any requests until the application context is successfully initialized. The error can stem from missing beans, circular dependencies, configuration property issues, database connection failures, missing auto-configuration, or incompatible bean definitions.
The Error You'll See
```java // Application startup failure Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2026-04-08T19:30:00.000Z ERROR 12345 --- [main] o.s.boot.SpringApplication : Application run failed
// Bean creation exception org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed
// Dependency injection failure org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderController': Unsatisfied dependency expressed through field 'orderService'
// Circular dependency org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'serviceA': Requested bean is currently in creation: Is there an unresolvable circular reference?
// Missing bean org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.service.EmailService' available
// Configuration property binding org.springframework.beans.factory.BindException: Could not bind properties to 'ApplicationProperties'
// Database connection failure org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection
// Multiple bean candidates org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.repository.UserRepository' available: expected single matching bean but found 2
// Auto-configuration failure org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to configure a DataSource ```
Why This Happens
- 1.Missing bean definitions: A required bean isn't defined (missing
@Component,@Service,@Repository,@Bean) or component scanning isn't configured properly. - 2.Dependency injection failures: Required dependencies aren't available, have wrong type, or aren't qualified correctly.
- 3.Circular dependencies: Two or more beans depend on each other, creating an unresolvable cycle.
- 4.Configuration property issues: Missing required properties, invalid property values, or incorrect property binding.
- 5.Database connection problems: Database not available, wrong connection string, authentication failure, or missing driver.
- 6.Missing auto-configuration: Required starters not included, or auto-configuration excluded.
- 7.Bean name conflicts: Multiple beans with same name or type without proper qualification.
- 8.Constructor injection issues: No default constructor and no proper constructor injection configuration.
- 9.Profile-specific configurations: Missing beans or configurations for the active profile.
- 10.Version incompatibilities: Spring Boot version incompatible with dependencies or Java version.
Step 1: Analyze the Stack Trace
Read the error output carefully:
```bash # Run with debug logging java -jar myapp.jar --debug
# Or with environment variable SPRING_PROFILES_ACTIVE=dev java -jar myapp.jar
# Run with full stack trace java -Ddebug=true -jar myapp.jar
# Check application logs tail -f logs/application.log
# Maven mvn spring-boot:run -Dspring-boot.run.arguments=--debug
# Gradle gradle bootRun --args='--debug' ```
- 1.Key sections to examine:
- 2.Root cause (usually at the bottom of stack trace)
- 3.Bean creation path (which beans failed to create)
- 4.Injection points (which dependencies couldn't be satisfied)
- 5.Configuration report (auto-configuration status)
```java // Look for the caused by section Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.service.EmailService' available
// This tells you exactly what's missing - EmailService bean ```
Step 2: Fix Missing Bean Issues
Ensure beans are properly defined:
```java // Missing @Service annotation // BEFORE - This class won't be detected package com.example.service;
public class EmailService { public void sendEmail(String to, String subject, String body) { // Implementation } }
// AFTER - Add @Service annotation package com.example.service;
import org.springframework.stereotype.Service;
@Service public class EmailService { public void sendEmail(String to, String subject, String body) { // Implementation } } ```
Configure component scanning:
```java // Main application class @SpringBootApplication // @SpringBootApplication includes @ComponentScan // Scans current package and subpackages
// If beans are in different packages @SpringBootApplication @ComponentScan(basePackages = { "com.example.controller", "com.example.service", "com.example.repository", "com.example.config" }) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
// Alternative: Use @Import @SpringBootApplication @Import({EmailConfig.class, DatabaseConfig.class}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
// Using @Bean method @Configuration public class ServiceConfig {
@Bean public EmailService emailService() { return new EmailService(); }
@Bean @ConditionalOnMissingBean public NotificationService notificationService() { return new DefaultNotificationService(); } } ```
Step 3: Fix Dependency Injection
Properly inject dependencies:
```java // BEFORE - Field injection (not recommended, but works) @Service public class UserService { @Autowired private UserRepository userRepository;
@Autowired private EmailService emailService; }
// AFTER - Constructor injection (recommended) @Service public class UserService { private final UserRepository userRepository; private final EmailService emailService;
public UserService(UserRepository userRepository, EmailService emailService) { this.userRepository = userRepository; this.emailService = emailService; } }
// With Lombok (reduces boilerplate) @Service @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; private final EmailService emailService; }
// Optional dependencies @Service public class NotificationService { private final Optional<EmailService> emailService;
public NotificationService(Optional<EmailService> emailService) { this.emailService = emailService; }
public void notify(String message) { emailService.ifPresent(svc -> svc.sendEmail("admin@example.com", "Notification", message)); } }
// Using @Qualifier for multiple implementations @Service public class NotificationManager { private final NotificationService notificationService;
public NotificationManager( @Qualifier("emailNotificationService") NotificationService notificationService ) { this.notificationService = notificationService; } }
// Define with @Primary @Service @Primary public class EmailNotificationService implements NotificationService { // Implementation }
@Service public class SmsNotificationService implements NotificationService { // Implementation } ```
Step 4: Resolve Circular Dependencies
Break circular dependencies:
```java // CIRCULAR DEPENDENCY PROBLEM @Service public class ServiceA { private final ServiceB serviceB;
public ServiceA(ServiceB serviceB) { this.serviceB = serviceB; } }
@Service public class ServiceB { private final ServiceA serviceA;
public ServiceB(ServiceA serviceA) { this.serviceA = serviceA; } }
// SOLUTION 1: Use @Lazy @Service public class ServiceA { private final ServiceB serviceB;
public ServiceA(@Lazy ServiceB serviceB) { this.serviceB = serviceB; } }
// SOLUTION 2: Use setter injection @Service public class ServiceA { private ServiceB serviceB;
@Autowired public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB; } }
// SOLUTION 3: Refactor to remove circular dependency // Extract shared logic to a third service @Service public class SharedService { // Common logic }
@Service public class ServiceA { private final SharedService sharedService;
public ServiceA(SharedService sharedService) { this.sharedService = sharedService; } }
@Service public class ServiceB { private final SharedService sharedService;
public ServiceB(SharedService sharedService) { this.sharedService = sharedService; } }
// SOLUTION 4: Use ApplicationContext to get bean lazily @Service public class ServiceA implements ApplicationContextAware { private ApplicationContext applicationContext; private ServiceB serviceB;
@Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; }
private ServiceB getServiceB() { if (serviceB == null) { serviceB = applicationContext.getBean(ServiceB.class); } return serviceB; } }
// Allow circular references (not recommended) // application.properties spring.main.allow-circular-references=true ```
Step 5: Fix Configuration Properties
Handle configuration property issues:
```java // Define configuration properties @ConfigurationProperties(prefix = "app") @Component public class AppProperties { private String name; private int timeout; private List<String> servers;
// Getters and setters }
// Enable configuration properties @SpringBootApplication @EnableConfigurationProperties(AppProperties.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
// application.yml app: name: My Application timeout: 30000 servers: - server1.example.com - server2.example.com
// Validate properties @ConfigurationProperties(prefix = "app") @Validated public class AppProperties { @NotBlank private String name;
@Min(1000) @Max(60000) private int timeout;
@NotEmpty private List<String> servers;
// Getters and setters }
// Required properties @ConfigurationProperties(prefix = "app") public class AppProperties { @NotNull private String apiKey; // Required, will fail if not set
// Getters and setters }
// application.yml app: api-key: ${API_KEY:} # From environment variable
// Handle missing optional properties @ConfigurationProperties(prefix = "app") public class AppProperties { private String optionalValue = "default"; // Has default private Duration timeout = Duration.ofSeconds(30); } ```
Step 6: Fix Database Configuration
Configure database properly:
```java // Basic database configuration // application.yml spring: datasource: url: jdbc:postgresql://localhost:5432/mydb username: ${DB_USERNAME:postgres} password: ${DB_PASSWORD:postgres} driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: validate show-sql: true
// Multiple datasources @Configuration public class DatabaseConfig {
@Bean @Primary @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); }
@Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); }
@Bean @Primary public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.domain.primary") .persistenceUnit("primary") .build(); } }
// Handle missing database (for testing/development) @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
// Exclude DataSource auto-configuration if not needed @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
// Embedded database for testing @TestConfiguration public class TestDatabaseConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .build(); } } ```
Step 7: Debug Bean Creation
Create debugging tools:
```java // Application listener to debug bean creation @Component public class BeanDebugListener implements ApplicationListener<ContextRefreshedEvent> {
@Override public void onApplicationEvent(ContextRefreshedEvent event) { ApplicationContext context = event.getApplicationContext();
String[] beanNames = context.getBeanDefinitionNames(); Arrays.sort(beanNames);
System.out.println("=== All Beans ==="); for (String beanName : beanNames) { Object bean = context.getBean(beanName); System.out.println(beanName + " : " + bean.getClass().getName()); } } }
// Debug auto-configuration @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); app.setAdditionalProfiles("debug"); app.run(args); } }
// Check condition evaluation report @SpringBootApplication public class Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
ConditionEvaluationReport report = context.getBean(ConditionEvaluationReport.class); System.out.println(report); } }
// Print bean dependencies @Component public class BeanDependencyPrinter implements ApplicationListener<ContextRefreshedEvent> {
@Override public void onApplicationEvent(ContextRefreshedEvent event) { ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory) event.getApplicationContext().getAutowireCapableBeanFactory();
for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
if (definition instanceof AbstractBeanDefinition) { System.out.println("Bean: " + beanName); System.out.println(" Depends on: " + Arrays.toString(definition.getDependsOn())); } } } } ```
Step 8: Handle Profile-Specific Beans
Configure beans for specific profiles:
```java // Profile-specific configuration @Configuration @Profile("dev") public class DevConfig {
@Bean public EmailService emailService() { return new MockEmailService(); // Mock for development } }
@Configuration @Profile("prod") public class ProdConfig {
@Bean public EmailService emailService() { return new SmtpEmailService(); // Real for production } }
// Profile-specific properties // application-dev.yml spring: datasource: url: jdbc:h2:mem:testdb
// application-prod.yml spring: datasource: url: jdbc:postgresql://prod-db:5432/mydb
// Conditional bean creation @Configuration public class FeatureConfig {
@Bean @ConditionalOnProperty(name = "feature.email.enabled", havingValue = "true") public EmailService emailService() { return new SmtpEmailService(); }
@Bean @ConditionalOnMissingBean(EmailService.class) public EmailService noOpEmailService() { return new NoOpEmailService(); }
@Bean @ConditionalOnClass(name = "org.springframework.data.redis.connection.RedisConnectionFactory") public CacheService redisCacheService() { return new RedisCacheService(); } } ```
Step 9: Test Configuration
Create tests to verify configuration:
```java @SpringBootTest class ApplicationStartupTest {
@Autowired private ApplicationContext applicationContext;
@Test void contextLoads() { // Test passes if application context starts successfully }
@Test void allRequiredBeansArePresent() { assertNotNull(applicationContext.getBean(UserService.class)); assertNotNull(applicationContext.getBean(EmailService.class)); assertNotNull(applicationContext.getBean(UserRepository.class)); }
@Test void propertiesAreBound() { AppProperties properties = applicationContext.getBean(AppProperties.class); assertNotNull(properties.getName()); assertTrue(properties.getTimeout() > 0); } }
// Test specific configuration @SpringBootTest @ActiveProfiles("test") @TestPropertySource(properties = { "spring.datasource.url=jdbc:h2:mem:testdb", "app.api-key=test-key" }) class TestConfig { // Tests }
// Slice tests for specific layers @WebMvcTest(UserController.class) class UserControllerTest { // Test controllers only }
@DataJpaTest class UserRepositoryTest { // Test JPA only } ```
Step 10: Create Startup Diagnostic Tool
Build comprehensive diagnostics:
```java @Component public class StartupDiagnostic implements ApplicationRunner {
private static final Logger log = LoggerFactory.getLogger(StartupDiagnostic.class);
@Override public void run(ApplicationArguments args) { log.info("=== Application Startup Diagnostics ===");
// System info log.info("Java Version: {}", System.getProperty("java.version")); log.info("Spring Boot Version: {}", SpringBootVersion.getVersion()); log.info("Active Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
// Check critical beans checkBean("userService", UserService.class); checkBean("userRepository", UserRepository.class);
// Check properties checkProperty("spring.datasource.url"); checkProperty("app.api-key", false); // Optional
log.info("=== Startup Complete ==="); }
@Autowired private Environment environment;
@Autowired private ApplicationContext context;
private void checkBean(String name, Class<?> type) { try { Object bean = context.getBean(type); log.info("Bean '{}' of type {} is available", name, type.getSimpleName()); } catch (NoSuchBeanDefinitionException e) { log.error("MISSING BEAN: '{}' of type {}", name, type.getSimpleName()); } }
private void checkProperty(String key) { checkProperty(key, true); }
private void checkProperty(String key, boolean required) { String value = environment.getProperty(key); if (value != null) { log.info("Property '{}' is set", key); } else if (required) { log.error("MISSING PROPERTY: '{}'", key); } else { log.warn("Optional property '{}' is not set", key); } } } ```
Checklist
| Step | Action | Verified |
|---|---|---|
| 1 | Analyzed the stack trace | ☐ |
| 2 | Fixed missing bean issues | ☐ |
| 3 | Fixed dependency injection | ☐ |
| 4 | Resolved circular dependencies | ☐ |
| 5 | Fixed configuration properties | ☐ |
| 6 | Fixed database configuration | ☐ |
| 7 | Debugged bean creation | ☐ |
| 8 | Handled profile-specific beans | ☐ |
| 9 | Created test configuration | ☐ |
| 10 | Created startup diagnostic tool | ☐ |
Verify the Fix
- 1.Run application:
- 2.```bash
- 3.mvn spring-boot:run
- 4.
` - 5.Check logs:
- 6.```bash
- 7.tail -f logs/application.log
- 8.
` - 9.Test endpoints:
- 10.```bash
- 11.curl http://localhost:8080/actuator/health
- 12.
`
Related Issues
- [Fix Java Spring Bean Creation Exception](/articles/fix-java-spring-bean-creation-exception)
- [Fix Spring Boot Auto Configuration Failed](/articles/fix-spring-boot-auto-configuration-failed)
- [Fix Spring Boot Database Connection Failed](/articles/fix-spring-boot-database-connection-failed)
- [Fix Spring Security Configuration Error](/articles/fix-spring-security-configuration-error)
- [Fix Spring Boot Property Binding Failed](/articles/fix-spring-boot-property-binding-failed)