strimzi / strimzi-kafka-bridge

An HTTP bridge for Apache Kafka®

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bad Request] Body application/vnd.kafka.json.v2+json parsing error: Null body"

cgalmarini opened this issue · comments

Hi, in the company I work for we are starting to implement Kafka (deployed on Openshift platform), so we're working on a very simple demo case.

We're facing an issue Posting to /topics/{topic-name}.
Other endpoints consumptions such as GETs and other POSTS work fine, for example POST to /consumers/{new-consumer} with a body as JSON and content type application/json.
Kafka bridge version is 0.27

Bridge yaml:

apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaBridge
metadata:
  creationTimestamp: '2024-03-25T12:43:42Z'
  generation: 4
  managedFields:
    - apiVersion: kafka.strimzi.io/v1beta2
      fieldsType: FieldsV1
      fieldsV1:
        'f:spec':
          .: {}
          'f:bootstrapServers': {}
          'f:http':
            .: {}
            'f:port': {}
          'f:logging':
            .: {}
            'f:loggers':
              .: {}
              'f:logger.send.level': {}
              'f:logger.send.name': {}
              'f:rootLogger.level': {}
            'f:type': {}
          'f:replicas': {}
      manager: Mozilla
      operation: Update
      time: '2024-03-25T13:53:37Z'
    - apiVersion: kafka.strimzi.io/v1beta2
      fieldsType: FieldsV1
      fieldsV1:
        'f:status':
          .: {}
          'f:conditions': {}
          'f:labelSelector': {}
          'f:observedGeneration': {}
          'f:replicas': {}
          'f:url': {}
      manager: strimzi-cluster-operator
      operation: Update
      subresource: status
      time: '2024-03-26T12:23:58Z'
  name: a-bridge
  namespace: cgalmari-amq-dev
  resourceVersion: '1345962103'
  uid: 6d7ed7d0-7b24-4a11-a6d6-61660bb7021f
spec:
  bootstrapServers: 'my-cluster-kafka-bootstrap:9092'
  http:
    port: 8080
  logging:
    loggers:
      logger.send.level: TRACE
      logger.send.name: http.openapi.operation.send
      rootLogger.level: TRACE
    type: inline
  replicas: 1
status:
  conditions:
    - lastTransitionTime: '2024-03-26T12:23:58.180330411Z'
      status: 'True'
      type: Ready
  labelSelector: >-
    strimzi.io/cluster=a-bridge,strimzi.io/name=a-bridge-bridge,strimzi.io/kind=KafkaBridge
  observedGeneration: 4
  replicas: 1
  url: 'http://a-bridge-bridge-service.cgalmari-amq-dev.svc:8080'

Request:

curl --location 'https://bridge-route-cgalmari-amq-dev.apps.ocp01-noprod.ocplasegunda-np.com.ar/topics/my-topic' \
--header 'Content-Type: application/vnd.kafka.json.v2+json' \
--header 'Cookie: 53b25721daaed00989bc096ba5f3b11c=c18d86121f7d9968727e74348d804998' \
--data '{
    "records": [
        {
            "value": "sales-lead-0001"
        }
    ]
}'

Response: 400 Bad request

{"error_code":400,"message":"[Bad Request] Body application/vnd.kafka.json.v2+json parsing error: Null body"}

Bridge log:

2024-03-26 13:27:29 TRACE [vert.x-eventloop-thread-0] RoutingContext: - Route matches: RouteState{metadata=null, path='null', name=null, order=1, enabled=true, methods=null, consumes=null, emptyBodyPermittedWithConsumes=false, produces=null, contextHandlers=[io.vertx.ext.web.handler.impl.BodyHandlerImpl@74ba64fd], failureHandlers=null, added=true, pattern=null, groups=null, useNormalizedPath=true, namedGroupsInRegex=null, virtualHostPattern=null, pathEndsWithSlash=false, exclusive=false, exactPath=true}
2024-03-26 13:27:29 TRACE [vert.x-eventloop-thread-0] RoutingContext: - Calling the  handler
2024-03-26 13:27:29 TRACE [vert.x-eventloop-thread-0] RoutingContext: - Route matches: RouteState{metadata=null, path='null', name=/topics/{topicname}, order=10, enabled=true, methods=[POST], consumes=null, emptyBodyPermittedWithConsumes=false, produces=[io.vertx.ext.web.impl.ParsableMIMEValue@1167bb2d], contextHandlers=[io.vertx.ext.web.handler.impl.ResponseContentTypeHandlerImpl@28ee89a6, io.vertx.ext.web.validation.impl.ValidationHandlerImpl@21fab8f8, io.strimzi.kafka.bridge.http.HttpBridge$1@173d1ce6], failureHandlers=null, added=true, pattern=\Q/topics/\E(?<p0>[^\!\*\'\(\)\;\@\&\+\$\/\?\#\[\]]*)?, groups=[topicname], useNormalizedPath=true, namedGroupsInRegex=[p0], virtualHostPattern=null, pathEndsWithSlash=false, exclusive=false, exactPath=true}
2024-03-26 13:27:29 TRACE [vert.x-eventloop-thread-0] RoutingContext: - Calling the  handler
2024-03-26 13:27:29 DEBUG [vert.x-eventloop-thread-0] RoutingContext: - RoutingContext failure (400)
io.vertx.ext.web.validation.BodyProcessorException: [Bad Request] Body application/vnd.kafka.json.v2+json parsing error: Null body
	at io.vertx.ext.web.validation.BodyProcessorException.createParsingError(BodyProcessorException.java:52) ~[io.vertx.vertx-web-validation-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.validation.impl.body.JsonBodyProcessorImpl.process(JsonBodyProcessorImpl.java:33) ~[io.vertx.vertx-web-validation-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.validation.impl.ValidationHandlerImpl.validateBody(ValidationHandlerImpl.java:247) ~[io.vertx.vertx-web-validation-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.validation.impl.ValidationHandlerImpl.handle(ValidationHandlerImpl.java:143) ~[io.vertx.vertx-web-validation-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.validation.impl.ValidationHandlerImpl.handle(ValidationHandlerImpl.java:18) ~[io.vertx.vertx-web-validation-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1286) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:140) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:144) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.handler.impl.ResponseContentTypeHandlerImpl.handle(ResponseContentTypeHandlerImpl.java:54) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.handler.impl.ResponseContentTypeHandlerImpl.handle(ResponseContentTypeHandlerImpl.java:28) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1286) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:144) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.handler.impl.BodyHandlerImpl.handle(BodyHandlerImpl.java:95) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.handler.impl.BodyHandlerImpl.handle(BodyHandlerImpl.java:45) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1286) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:144) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:68) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:37) ~[io.vertx.vertx-web-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:67) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:30) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:179) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:174) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:159) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.onHttpRequestChannelRead(WebSocketServerExtensionHandler.java:160) ~[io.netty.netty-codec-http-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:83) ~[io.netty.netty-codec-http-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.vertx.core.http.impl.Http1xUpgradeToH2CHandler.channelRead(Http1xUpgradeToH2CHandler.java:124) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[io.netty.netty-codec-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[io.netty.netty-codec-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38) ~[io.vertx.vertx-core-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[io.netty.netty-transport-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[io.netty.netty-common-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[io.netty.netty-common-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[io.netty.netty-common-4.1.100.Final-redhat-00001.jar:4.1.100.Final-redhat-00001]
	at java.lang.Thread.run(Thread.java:840) ~[?:?]
Caused by: io.vertx.ext.web.validation.MalformedValueException: Null body
	at io.vertx.ext.web.validation.impl.body.JsonBodyProcessorImpl.process(JsonBodyProcessorImpl.java:34) ~[io.vertx.vertx-web-validation-4.4.6.redhat-00002.jar:4.4.6.redhat-00002]
	... 61 more

A similar issue was found before (#726) solved on 0.24.0 release.
That issue faced when CORS was enabled, but I'm facing it no matter CORS, from yaml definition you can see that CORS is not enabled.

Any ideas on how can we deal with this will be appreciated. Thanks in advance

From the log it's clear you are using a Red Hat product and not the upstream Strimzi release. You should go through the proper Red Hat support for this.

Thank you, we finally realized that the problem was a misconfiguration involving kafka broker and kafka topic.
The broker is setup with a min in sync replicas = 2 but the topic was set with just one replica and no min in sync replica setted, so as far as I understand broker settings are inherited regarding to this point. Setting min in sync replicas to 1 for the topic fixed this issue.

@cgalmarini tbh I don't see how your mistake on the topic configuration had an impact on the issue you saw. The mistake above was coming well before the request goes to Kafka from the bridge. It's the part of the HTTP interface which had problem to parse the body and Kafka was not involved yet.
I think you changed something else which fixed the issue.
Anyway happy you fixed the problem, I will close the issue then.