Hi there,

I have inspected the following (somewhat related) issues, but none of them solves the problem I am experiencing: * #1393 * #1446 * #1014 * #1060 * #984

Some specs of my application: - Spring Cloud version: Greenwhich.SR3 - Spring Cloud Config Server: 2.1.4.RELEASE - Spring Boot 2.1.8

I tried several setups, which are described below. I could not get either of them working, thus leaving me stuck for now. Help or advice is greatly appreciated.

Intended Setup:

My setup is as follows: * config server with a bootstrap.yml having spring.cloud.config.server.bootstrap: true * a GitHub repo with configurations * a Hashicorp vault (v.1.2.3) with secrets (referenced in GitHub configurations) * a config-server setup with a composite environment repository setup.

The composite configuration looks as follows:

spring:
  application.name: config-server

  profiles:
    active: composite

  # Config Server Configurations
  cloud:
    config:
      server:
        # Load configurations of config-server itself from Git repository as well. 
        # See: https://cloud.spring.io/spring-cloud-config/reference/html/#_embedding_the_config_server
        bootstrap: true
        composite:
          # Hashicorp Vault repository for storage and reference of secrets / credentials.
          - type: vault 
            host: localhost
            port: 8200
            kvVersion: 2
          # GitHub repository for bootstrapping and runtime configurations
          - type: git
            uri: https://github.com/FWinkler79/SpringCloudPlatform-Configs.git
            deleteUntrackedBranches: true

When I run config-server with this setup, I get the following error:

java.lang.IllegalStateException: No HttpServletRequest available
    at org.springframework.cloud.config.server.environment.HttpRequestConfigTokenProvider.getToken(HttpRequestConfigTokenProvider.java:41) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.getToken(VaultEnvironmentRepository.java:218) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.read(VaultEnvironmentRepository.java:209) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.findOne(VaultEnvironmentRepository.java:147) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:61) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator.locate(EnvironmentRepositoryPropertySourceLocator.java:55) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:97) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:623) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:367) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]

So I tried what was suggested in #1446, i.e. to add spring.cloud.config.server.vault.token

Option 1:

spring:
  cloud:
    config:
      server:
        vault:
          token: root   # Option 1

       bootstrap: true
        composite:
          # Hashicorp Vault repository for storage and reference of secrets / credentials.
          - type: vault 
           ...
          # GitHub repository for bootstrapping and runtime configurations
          - type: git
            ...

As a result, I get the following error:

2019-09-30 15:35:37.714 DEBUG [config-server,,,] 69017 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : Application failed to start due to an exception

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'configTokenProvider' defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.VaultConfiguration; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]] for bean 'configTokenProvider': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider.class]] bound.
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:893) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:274) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:203) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:114) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:71) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:342) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:305) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]

Option 2:

spring:
  cloud:
    config:
      server:
       bootstrap: true
        composite:
          # Hashicorp Vault repository for storage and reference of secrets / credentials.
          - type: vault 
            token: root   # Option 2
           ...
          # GitHub repository for bootstrapping and runtime configurations
          - type: git
            ...

As a result, I get the following error:

2019-09-30 15:40:23.455 DEBUG [config-server,,,] 69050 --- [           main] .c.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: unknown
2019-09-30 15:40:23.460 DEBUG [config-server,,,] 69050 --- [           main] o.s.boot.diagnostics.FailureAnalyzers    : FailureAnalyzer org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer@7397c6 failed

java.lang.TypeNotPresentException: Type org.springframework.jdbc.CannotGetJdbcConnectionException not present
    at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117) ~[na:na]
    at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) ~[na:na]
    at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:na]
    at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68) ~[na:na]
    at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138) ~[na:na]
    at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:na]
    at java.base/sun.reflect.generics.repository.ClassRepository.computeSuperclass(ClassRepository.java:104) ~[na:na]
    at java.base/sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:86) ~[na:na]
    at java.base/java.lang.Class.getGenericSuperclass(Class.java:950) ~[na:na]
    at org.springframework.core.ResolvableType.getSuperType(ResolvableType.java:466) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.core.ResolvableType.as(ResolvableType.java:455) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.core.ResolvableType.forClass(ResolvableType.java:1037) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.getCauseType(AbstractFailureAnalyzer.java:56) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.analyze(AbstractFailureAnalyzer.java:33) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.diagnostics.FailureAnalyzers.analyze(FailureAnalyzers.java:110) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.diagnostics.FailureAnalyzers.reportException(FailureAnalyzers.java:103) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:813) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:798) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
    at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
    at java.base/java.lang.Class.forName(Class.java:398) ~[na:na]
    at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) ~[na:na]
    ... 21 common frames omitted

2019-09-30 15:40:23.462 ERROR [config-server,,,] 69050 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: No HttpServletRequest available
    at org.springframework.cloud.config.server.environment.HttpRequestConfigTokenProvider.getToken(HttpRequestConfigTokenProvider.java:41) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.getToken(VaultEnvironmentRepository.java:218) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.read(VaultEnvironmentRepository.java:209) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.findOne(VaultEnvironmentRepository.java:147) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.CompositeEnvironmentRepository.findOne(CompositeEnvironmentRepository.java:61) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator.locate(EnvironmentRepositoryPropertySourceLocator.java:55) ~[spring-cloud-config-server-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:97) ~[spring-cloud-context-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:623) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:367) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
    at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]

Alternative Setup:

I also tried without composite:

spring:
  application.name: config-server

  # Activate the config-server 'composite' profile
  # so that it can load its own configs from Git.
  profiles:
    active: vault, git

  # Config Server Configurations
  cloud:
    config:
      server:
        # Load configurations of config-server itself from Git repository as well. 
        # See: https://cloud.spring.io/spring-cloud-config/reference/html/#_embedding_the_config_server
        bootstrap: true

        # Hashicorp Vault repository for storage and reference of secrets / credentials.
        vault: 
          host: localhost
          port: 8200
          kvVersion: 2
          #token: root  # does neither work with nor without it.

        # GitHub repository for bootstrapping and runtime configurations
        git:
          uri: https://github.com/FWinkler79/SpringCloudPlatform-Configs.git
          deleteUntrackedBranches: true

In this setup I cannot get it to work no matter whether the spring.cloud.config.server.vault.token is set or not - getting the same kind of exceptions as above.

Sample

You can find a sample where this is shown here.

To reproduce: * Start the Vault, executing ./scripts/startDevVault.sh * Start config-server

Comment From: deciojr

After 4-5 days trying to implement this, I found a workaround with the following configuration

Spring cloud version: Greenwich.SR3 Spring Cloud Config Server: 2.1.4.RELEASE Spring boot: 2.1.8

bootstrap.yml

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        bootstrap: true
        composite:
          - type: vault
            kv-version: 2
            token:  VAULT_TOKEN
        vault:
          token: VAULT_TOKEN
  profiles:
    active: composite
  main:
    allow-bean-definition-overriding: true

application.yml

server:
  port: 8888
spring:
   cloud:
    config:
      server:
        composite:
          - type: git
            uri: GIT_URI
            username: ${git.username}
            password: ${git.password}

The only problem is that, when i query the config server at its default profile, the vault configuration gets repeated

Spring Cloud Config Config Server using GitHub AND Vault AND bootstrap = true not working

If anyone knows how to prevent the above or the right way to do this, it would still be very much appreciated

Comment From: FWinkler79

Hi @deciojr,

great that you had a look at it, it's much appreciated. I am just not sure we should call it a "workaround", since having the vault configuration duplicated is not really clean and kind of unexpected. What do you think?

Cheers!

Comment From: deciojr

I agree. English isn't my primary language, so I couldn't think of any other word at the time.

Comment From: FWinkler79

I am wondering if this is something that the Spring team would be willing to fix.

Generally, I see a benefit in a config-server being able to bootstrap its own config from the very GitHub repo it uses to serve other services' configs from. And it's also obvious that an integration with a password Vault is a great benefit.

However, this bug makes that combination impossible to use - when I would have thought this should be the preferred setup.

How likely is it that this is getting fixed? Just asking, since otherwise we will need to go for a different, less optimal solution.

Comment From: spencergibb

There have been new options for authenticating vault. See #1475. Can this be used here?

Comment From: FWinkler79

Thanks for the hint. Unfortunately that does not help here. In the meantime I think I found the bug that causes this issue.

If evth. is configured right (i.e. as documented) I keep getting the error:

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'configTokenProvider', defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

2020-01-14 18:25:27.739 DEBUG [config-server,,,] 99242 --- [           main] .c.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: unknown
2020-01-14 18:25:27.739 ERROR [config-server,,,] 99242 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'configTokenProvider' defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.VaultConfiguration; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/VaultConfiguration.class]] for bean 'configTokenProvider': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider; factoryMethodName=configTokenProvider; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration$DefaultConfigTokenProvider.class]] bound.
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:927) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:287) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:337) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:242) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:206) ~[spring-cloud-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:117) ~[spring-cloud-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:74) ~[spring-cloud-context-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at com.equalities.cloud.config.server.ConfigServer.main(ConfigServer.java:17) ~[classes/:na]

So I checked why this is the case, and found that there are two classes involved, one of which is not correct: 1. EnvironmentRepositoryConfiguration 1. VaultConfiguration

EnvironmentRepositoryConfiguration imports VaultConfiguration, and expects that it defines a bean named configTokenProvider. In case that bean is not defined, EnvironmentRepositoryConfiguration will declare its default fallback like this:

@Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean(ConfigTokenProvider.class)
    protected static class DefaultConfigTokenProvider {

        @Bean
        public ConfigTokenProvider configTokenProvider(
                ObjectProvider<HttpServletRequest> httpRequest) {
            return new HttpRequestConfigTokenProvider(httpRequest);
        }

However, since the fallback is declared inside a static inner class, Spring evaluates that first, thus not giving VaultConfiguration a chance to provide its (proper) configTokenProvider. This causes the error, and the default configTokenProvider simply does not work.

Note: this could even be a problem in other cases as well, as the list of imported configurations on EnvironmentRepositoryConfiguration is quite extensive.

A Possible Fix

A possible fix should be to change EnvironmentRepositoryConfiguration to not declare the fallback configTokenProvider from within an inner configuration class, but via a @Bean method like this:

// all @Imports here...
public class EnvironmentRepositoryConfiguration {
...
    @Bean
    @ConditionalOnMissingBean(ConfigTokenProvider.class)
    public ConfigTokenProvider configTokenProvider(ObjectProvider<HttpServletRequest> httpRequest) {
         return new HttpRequestConfigTokenProvider(httpRequest);
    }
...
}

I was able to reproduce the erroneous behaviour in a test rig given here.

Is there a chance this can be fixed?

Comment From: spencergibb

mark yours as @Primary?

Comment From: spencergibb

PRs welcome.

Comment From: FWinkler79

Since there is no bean of mine involved, but only framework beans that I cannot mark nor re-declare, I cannot mark anything as @Primary.

I created a PR that fixes this issue, so that the intended setup will work. If the PR is merged, I will add a final description here, that shows the setup.

I tested this in my local environment, using this project setup.