Spring Boot / Editorial solution guide

Diagnose missing, ambiguous, and cyclic beans

Find the failing composition boundary without widening scans, enabling every profile, or hiding dependency errors through broad overrides.

About 3 min readContent reviewed

Read-only knowledge base ยท No public comments

Recognize the symptoms

Startup or a test context fails with an UnsatisfiedDependencyException, NoSuchBeanDefinitionException, NoUniqueBeanDefinitionException, or BeanCurrentlyInCreationException. The outer Failed to load ApplicationContext message is often only a wrapper.

An application may work under one profile or IDE launch and fail in its packaged environment because actual sources, classpath, or bean conditions differ.

Understand the likely causes

  • A required type may lie outside discovery, be excluded by a profile/condition, have no implementation, have several unqualified candidates, or participate in a constructor cycle.
  • Manual construction can bypass the container, while an incompatible dependency override can fail during class loading rather than ordinary candidate selection. Preserve the first meaningful cause.

Capture the actual composition inputs

Record Boot/BOM and Java versions, artifact identity, active profiles, test slice, required type, and the earliest relevant cause. Inspect effective sources without printing secrets or the complete environment. A condition report can help in an approved local fixture, but do not launch the configured application or expose Actuator diagnostics merely to gather evidence for this guide.

Classify candidate absence, ambiguity, and cycles

For absence, verify package scanning, explicit imports/registration, implementation type, and conditions. For ambiguity, identify why several implementations exist and select a meaningful qualifier or primary policy. For a cycle, draw the constructor graph and reconsider responsibilities. Enabling circular references or bean overriding globally can conceal a design error and change unrelated components; it is not an evidence-based universal repair.

Describe the expected failure in a limited fixture

The illustrative ApplicationContextRunner test defines a consumer that requires a Catalog but supplies none. It expects a startup failure with a missing-candidate cause. The fragment does not run and needs managed Boot test/AssertJ dependencies. It shows how to isolate one graph question without a web listener, datasource, or unrelated application bean; parsing the Java text alone would not verify that framework behavior.

java Illustrative missing-capability context test
package training.catalog;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;

class MissingCatalogFixture {
    interface Catalog {}
    record Consumer(Catalog catalog) {}
    @Configuration(proxyBeanMethods=false)
    static class NeedsCatalog {
        @Bean Consumer consumer(Catalog catalog) { return new Consumer(catalog); }
    }
    @Test void rejectsMissingCapability() {
        new ApplicationContextRunner().withUserConfiguration(NeedsCatalog.class)
            .run(context -> {
                assertThat(context).hasFailed();
                assertThat(context.getStartupFailure())
                    .hasRootCauseInstanceOf(NoSuchBeanDefinitionException.class);
            });
    }
}

This is intended framework evidence to execute later under controlled dependencies; no ApplicationContext was refreshed here.

Apply the narrow change supported by the graph

Register the intended implementation, correct an accidental package boundary, supply the approved profile/configuration, or resolve a genuine alternative explicitly. Separate a cycle into capabilities with a clear dependency direction where appropriate. If versions conflict, restore a coherent managed dependency set instead of adding annotations. Keep tests aligned with the actual production composition while restricting unrelated integrations.

Verify the fix

Verify the original failing context and intended profile combinations, then confirm exactly which candidate is used. Include a negative case proving missing or unauthorized configuration still fails clearly. Check resource cleanup and that the repair did not load a real datasource, scheduler, or client unnecessarily. Discovery of a test is not the same as executing its context assertions.

Keep it from recurring

  • Keep required constructor dependencies explicit, composition roots narrow, profiles reviewed, and managed versions coherent. Add a scoped context regression for the actual defect and preserve secret-safe artifact/configuration identity so the next failure can be correlated with the correct build.

Official references