spring-projects/spring-framework · error · BeanCreationException

Failed to invoke init method

Error message

Failed to invoke init method

What it means

Thrown by InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization() when invoking an init-annotated method fails with a Throwable that is NOT an InvocationTargetException — i.e., a reflective or infrastructure error rather than a business exception from the method body. Examples include IllegalAccessException (method not accessible) or generic Error types.

Solutions

  1. If the cause is InaccessibleObjectException or IllegalAccessException, ensure the method is accessible (public, or add --add-opens JVM flags).
  2. Inspect the cause throwable — if it is an Error, address the JVM-level issue.
  3. Verify the init annotation is on the correct method that still exists with the expected signature.

Example fix

// before
@PostConstruct
private void init() { ... } // private on module path

// after
@PostConstruct
public void init() { ... } // accessible
Defensive patterns

Strategy: try-catch

Validate before calling

null

Try / catch

try {
    context.getBean(MyBean.class);
} catch (BeanCreationException ex) {
    if (ex.getMessage().contains("Failed to invoke init method")) {
        Throwable cause = ex.getCause(); // IllegalAccessException, Error, etc.
        if (cause instanceof IllegalAccessException) {
            // fix method visibility or add --add-opens
        }
    }
}

Prevention

When it happens

Trigger: The init method cannot be invoked reflectively due to access restrictions (private method on a module path without --add-opens), or the invocation throws an Error (StackOverflowError, OutOfMemoryError, etc.). The catch(Throwable) at line 222 wraps these non-InvocationTargetException cases.

Common situations: Java module system blocking reflective access to a private init method (InaccessibleObjectException). Init method annotated but the method was removed or renamed in a class reload scenario. JVM-level errors during init.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/ca82931f2a543192. Report an issue: GitHub.

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java:223

	private static String[] safeMerge(String @Nullable [] existingNames, Collection<LifecycleMethod> detectedMethods) {
		Stream<String> detectedNames = detectedMethods.stream().map(LifecycleMethod::getIdentifier);
		Stream<String> mergedNames = (existingNames != null ?
				Stream.concat(detectedNames, Stream.of(existingNames)) : detectedNames);
		return mergedNames.distinct().toArray(String[]::new);
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
		}
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Override
	public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeDestroyMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
			if (logger.isDebugEnabled()) {

View on GitHub (pinned to 69bf83ad71)