Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Actuator AuditEvents Defaults to enabled, however seems to conflict with new Access.java constraints #43366

Closed
bashout opened this issue Dec 3, 2024 · 5 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@bashout
Copy link

bashout commented Dec 3, 2024

Explictly we are only using the health and info actuator endpoints. See the below config for relevant configuration:

management.endpoints.access.default=none
management.endpoint.info.access=read_only
management.endpoint.health.access=read_only
management.endpoints.web.exposure.include=health,info
management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=health 
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
management.endpoint.health.show-details=always
management.info.env.enabled=true

However since updating to Spring Boot 3.4.0 and using the new endpoint Access syntax, when attempting to run in our deployed environment we have found the following startup issue.

2024-12-03T16:21:40,628Z ERROR o.s.b.SpringApplication:857        Application run failed   java.lang.IllegalArgumentException: Invalid boolean value 'none'
        at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:55)
        at org.springframework.core.convert.support.StringToBooleanConverter.convert(StringToBooleanConverter.java:33)
        at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:358)
        at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
        ... 40 common frames omitted
Wrapped by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Boolean] for value [none]
        at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
        at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:182)
        at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:165)
        at org.springframework.core.env.AbstractPropertyResolver.convertValueIfNecessary(AbstractPropertyResolver.java:281)
        at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:82)
        at org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver.getProperty(ConfigurationPropertySourcesPropertyResolver.java:66)
        at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:568)
        at org.springframework.boot.actuate.autoconfigure.endpoint.PropertiesEndpointAccessResolver.determineDefaultAccess(PropertiesEndpointAccessResolver.java:65)
        at org.springframework.boot.actuate.autoconfigure.endpoint.PropertiesEndpointAccessResolver.<init>(PropertiesEndpointAccessResolver.java:58)
        at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330)
        at org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnAvailableEndpointCondition.getAccess(OnAvailableEndpointCondition.java:136)
        at org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnAvailableEndpointCondition.getAccessOutcome(OnAvailableEndpointCondition.java:130)
        at org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnAvailableEndpointCondition.getMatchOutcome(OnAvailableEndpointCondition.java:117)
        at org.springframework.boot.actuate.autoconfigure.endpoint.condition.OnAvailableEndpointCondition.getMatchOutcome(OnAvailableEndpointCondition.java:79)
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
        ... 26 common frames omitted
Wrapped by: java.lang.IllegalStateException: Error processing condition on org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
        at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:99)
        at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:233)
        at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:603)
        ... 23 common frames omitted
Wrapped by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class : Error processing condition on org.springframework.boot.actuate.autoconfigure.audit.AuditEventsEndpointAutoConfiguration
        at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:613)
        at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:836)
        at java.base/java.lang.Iterable.forEach(Iterable.java:75)
        at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:833)
        at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:803)
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:418)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
        at Application.main(Application.java:16)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)

This appears to be associated with the default being:
management.auditevents.enabled=true

We don't necessarily have a need for auditevents, though it seems to be a bug as it's trying to use the Access.java value of none and expecting a boolean

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 3, 2024
@wilkinsona
Copy link
Member

I don't think this is related to management.auditevents.enabled. The failure's occurring on line 65 of PropertiesEndpointAccessResolver:

This is reading the value of the management.endpoints.enabled-by-default.

Given the above, it would appear that management.endpoints.enabled-by-default has been set to none somewhere in your app's environment. It appears to be related to AuditEventsEndpointAutoConfiguration purely because that's the first auto-configuration that uses @ConditionalOnAvailableEndpoint to be processed. If you exclude that auto-configuration it'll then fail when processing org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration.

Please check your application's environment and correct the value of management.endpoints.enabled-by-default to be true or false.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Dec 3, 2024
@bashout
Copy link
Author

bashout commented Dec 3, 2024

We have removed all references to management.endpoints.enabled-by-default as it has been marked as deprecated, isn't this intended?

I do agree with the snippet provided and quintuple checking our configurations now. However since I've removed all references to it in our application files, I wouldn't expect it to be being configured.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 3, 2024
@wilkinsona
Copy link
Member

The property isn't set by default so I believe you must have missed an occurrence where it's being set to a non-boolean value. It could be coming from a system property or an environment variable, for example, not just from application configuration files. If you debug your application with a breakpoint on line 65 of PropertiesEndpointAccessResolver, you should be able to step through the resolution process to find which property source it's coming from.

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Dec 3, 2024
@bashout
Copy link
Author

bashout commented Dec 3, 2024

Happy to say you put us on the right path. Turns out our env vars had conflicting names with the underlying spring properties, thus were overruling. Naivety on my part. Appreciate the direction!

@bashout bashout closed this as completed Dec 3, 2024
@philwebb philwebb added status: invalid An issue that we don't feel is valid and removed status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged labels Dec 3, 2024
@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Dec 4, 2024
@wilkinsona
Copy link
Member

Good to hear that you figured it out. Thanks for letting us know.

Boot could be more helpful here by handling the ConversionFailedException and throwing an InvalidConfigurationPropertyValueException. That would turn the lengthy stack trace above that doesn't tell you about the origin of the property value into something like this instead:

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

Description:

Invalid value 'none' for configuration property 'management.endpoints.enabled-by-default' (originating from 'System Environment Property "MANAGEMENT_ENDPOINTS_ENABLED_BY_DEFAULT"'). Validation failed for the following reason:

Failed to convert from type [java.lang.String] to type [java.lang.Boolean] for value [none]

Action:

Review the value of the property with the provided reason.

I've opened #43378 to track this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants