kafka-ui
kafka-ui copied to clipboard
Fresh install: adding cluster ends with status 400 "config.properties.auth.oauth2 can not be null"
Issue submitter TODO list
- [x] I've looked up my issue in FAQ
- [x] I've searched for an already existing issues here
- [x] I've tried running
main-labeled docker image and the issue still persists there - [x] I'm running a supported version of the application which is listed here
Describe the bug (actual behavior)
When I run kafbat on completely basic settings lifted straight from README's "Quick start", clicking Submit on the new cluster form ends with status 400, with message "Fields validation failure", with details complaining about config.properties.auth.oauth2 being null.
The PUT request that attempts to add the cluster contains "auth": { "type": "DISABLED", "oauth2": null } (this is about kafbat's auth, not kafka's).
The validation complains about oauth2 being null, but it should be allowed to be null if I don't have kafbat auth.
Expected behavior
I expect the cluster to be added, even when I run kafbat without auth.
Your installation details
docker run -it -p 8080:8080 -e DYNAMIC_CONFIG_ENABLED=true ghcr.io/kafbat/kafka-ui (v1.4.2)
No actual running Kafka needed to reproduce, but the problem persist all the same if I enter connection to an actual Kafka.
Steps to reproduce
docker run -it -p 8080:8080 -e DYNAMIC_CONFIG_ENABLED=true ghcr.io/kafbat/kafka-ui- Open http://localhost:8080/ui/clusters/create-new-cluster
- Bootstrap servers:
localhost,9093(no other cluster config needed, and it doesn't matter if something actually runs there) - Press Submit
- 400 Bad Request: Fields validation failure
Screenshots
Logs
Clicking Submit results in this request:
PUT http://localhost:8080/api/config
With this body:
{
"config": {
"properties": {
"auth": {
"type": "DISABLED",
"oauth2": null // type=DISABLED and oauth2=null, as expected - but causes validation fail
},
"rbac": {
"roles": []
},
"webclient": {},
"kafka": {
"clusters": [
{
"name": "Test",
"bootstrapServers": "localhost:9093",
"properties": {},
"readOnly": false
}
]
}
}
}
}
And this response (status 400):
{
"code": 4001,
"message": "Fields validation failure",
"timestamp": 1764153973576,
"requestId": "f0ddeda3-66",
"fieldsErrors": [
{
"fieldName": "config.properties.auth.oauth2",
"restrictions": [
"nie może mieć wartości null"
]
}
],
"stackTrace": "org.springframework.web.bind.support.WebExchangeBindException: Validation failed for argument at index 0 in method: public reactor.core.publisher.Mono<org.springframework.http.ResponseEntity<java.lang.Void>> io.kafbat.ui.controller.ApplicationConfigController.restartWithConfig(reactor.core.publisher.Mono<io.kafbat.ui.model.RestartRequestDTO>,org.springframework.web.server.ServerWebExchange), with 1 error(s): [Field error in object 'restartRequestDTOMono' on field 'config.properties.auth.oauth2': rejected value [null]; codes [NotNull.restartRequestDTOMono.config.properties.auth.oauth2,NotNull.config.properties.auth.oauth2,NotNull.oauth2,NotNull.io.kafbat.ui.model.ApplicationConfigPropertiesAuthOauth2DTO,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [restartRequestDTOMono.config.properties.auth.oauth2,config.properties.auth.oauth2]; arguments []; default message [config.properties.auth.oauth2]]; default message [nie może mieć wartości null]] \n\tat org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.validate(AbstractMessageReaderArgumentResolver.java:289)\n\tSuppressed: The stacktrace has been enhanced by Reactor, refer to additional information below: \nError has been observed at the following site(s):\n\t*__checkpoint ⇢ Handler io.kafbat.ui.controller.ApplicationConfigController#restartWithConfig(Mono, ServerWebExchange) [DispatcherHandler]\n\t*__checkpoint ⇢ io.kafbat.ui.config.CorsGlobalConfiguration$$Lambda/0x00007b5ed6652fb8 [DefaultWebFilterChain]\n\t*__checkpoint ⇢ io.kafbat.ui.config.ReadOnlyModeFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ io.kafbat.ui.config.CustomWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ AuthorizationWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ ExceptionTranslationWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ LogoutWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ ServerRequestCacheWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ ReactorContextWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ HttpHeaderWriterWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]\n\t*__checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]\n\t*__checkpoint ⇢ HTTP PUT \"/api/config\" [ExceptionHandlingWebHandler]\nOriginal Stack Trace:\n\t\tat org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.validate(AbstractMessageReaderArgumentResolver.java:289)\n\t\tat org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.lambda$readBody$5(AbstractMessageReaderArgumentResolver.java:210)\n\t\tat reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:185)\n\t\tat reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74)\n\t\tat reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)\n\t\tat reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:158)\n\t\tat reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)\n\t\tat reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:299)\n\t\tat reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337)\n\t\tat reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2096)\n\t\tat reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:145)\n\t\tat reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)\n\t\tat reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260)\n\t\tat reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)\n\t\tat reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:481)\n\t\tat reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:273)\n\t\tat reactor.netty.channel.FluxReceive.request(FluxReceive.java:131)\n\t\tat reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164)\n\t\tat reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138)\n\t\tat reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164)\n\t\tat reactor.core.publisher.Operators$BaseFluxToMonoOperator.request(Operators.java:2066)\n\t\tat reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.request(FluxFilterFuseable.java:411)\n\t\tat reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.request(FluxMapFuseable.java:360)\n\t\tat reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.request(FluxContextWrite.java:136)\n\t\tat reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194)\n\t\tat reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2366)\n\t\tat reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74)\n\t\tat reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117)\n\t\tat reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onSubscribe(FluxContextWrite.java:101)\n\t\tat reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onSubscribe(FluxMapFuseable.java:265)\n\t\tat reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onSubscribe(FluxFilterFuseable.java:305)\n\t\tat reactor.core.publisher.Operators$BaseFluxToMonoOperator.onSubscribe(Operators.java:2050)\n\t\tat reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92)\n\t\tat reactor.core.publisher.FluxPeek$PeekSubscriber.onSubscribe(FluxPeek.java:171)\n\t\tat reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92)\n\t\tat reactor.netty.channel.FluxReceive.startReceiver(FluxReceive.java:170)\n\t\tat reactor.netty.channel.FluxReceive.lambda$subscribe$2(FluxReceive.java:148)\n\t\tat io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)\n\t\tat io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)\n\t\tat io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)\n\t\tat io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:405)\n\t\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998)\n\t\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\n\t\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)\n\t\tat java.base/java.lang.Thread.run(Thread.java:1583)\n"
}
Additional context
Issue doesn't happen on v1.3.0