java icon indicating copy to clipboard operation
java copied to clipboard

Json validation error in new version

Open editcriteria opened this issue 1 year ago • 11 comments

Describe the bug While trying to read the nodes of a server I got the following error:

java.lang.IllegalArgumentException: Expected the field `names` to be an array in the JSON string but got `null`

The line that throws the exception is V1ContainerImage.java:193 and in debug I noticed that in my case jsonObj.get("names") is JsonNull so the first condition of line 192 fails because it checks for null and the second fails because it is not an array. I tried the same call in versions 19.0.0 and even 20.0.1-legacy and I can read the nodes

Client Version 20.0.1

Kubernetes Version 1.29.1

Java Version Java 17

To Reproduce It happens on an internal server only when reading nodes

Expected behavior The Json response is parsed correctly

KubeConfig //

Server (please complete the following information):

  • OS: Linux
  • Environment container
  • Cloud /

editcriteria avatar Apr 15 '24 08:04 editcriteria

Can you provide the body of the response that you got? You should be able to get it with ApiException.getResponseBody()

brendandburns avatar Apr 15 '24 14:04 brendandburns

fwiw, I believe that this is either a bug in the openai spec or the kube api server.

If you look at the spec:

https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json

If you search for ContainerImage you'll see that it is described as an array of string. In JSON null is not the same as []

I believe it needs to be either specified as a oneof(array, null) in that schema or the API server should never return null

brendandburns avatar Apr 15 '24 20:04 brendandburns

Here is the part of the body that I think causes the error:

"images": [
    {
        "names": null,
        "sizeBytes": 974400966
    },
    ...
]

We are contacting a k0s server but the same call works with the legacy version of the client.

As a side note, the exception does not throw an ApiException, is it supposed to?

editcriteria avatar Apr 16 '24 07:04 editcriteria

Thanks for the additional details. I would have thought that it would throw ApiException, but I guess there's no corresponding try/catch block.

With 20.0.0 we moved to a different code generator which is why there is a difference here.

For now, using legacy is probably the right thing to do. We need a reproduction in upstream k8s, not k0s to determine if this is really a bug.

brendandburns avatar Apr 16 '24 23:04 brendandburns

I found the same error, which I can confirm is a bug, and the error message is as follows: java.lang.IllegalArgumentException: Expected the field namesto be an array in the JSON string but gotnull`

at io.kubernetes.client.openapi.models.V1ContainerImage.validateJsonObject(V1ContainerImage.java:193)
at io.kubernetes.client.openapi.models.V1NodeStatus.validateJsonObject(V1NodeStatus.java:547)
at io.kubernetes.client.openapi.models.V1Node.validateJsonObject(V1Node.java:284)`

pigstomach avatar Apr 22 '24 07:04 pigstomach

@pigstomach are you using k0s also? Or is this a true kubernetes api server?

brendandburns avatar May 24 '24 16:05 brendandburns

Ok, I found the problem (I think):

https://github.com/OpenAPITools/openapi-generator/issues/12549

We need to rev. past https://github.com/OpenAPITools/openapi-generator/commit/7a7309edb87902a92d4d0e7b142e4c17dfe5e2b3 in the generator, likely update to 7.x (maybe 7.4?)

brendandburns avatar May 24 '24 16:05 brendandburns

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle stale
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

k8s-triage-robot avatar Aug 22 '24 16:08 k8s-triage-robot

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle rotten
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten

k8s-triage-robot avatar Sep 21 '24 16:09 k8s-triage-robot

I'm also seeing this error. In my case it's when receiving a bookmark event.

I'm using version 21.0.1 of the client and version 1.31.0 of kubernetes.

I'm creating a watch and processing the responses with code that looks something like this:

try (Watch<V1Pod> watch = Watch.createWatch(client, api.listNamespacedPod("namespace")
        .timeoutSeconds(60)
        .watch(true)
        .allowWatchBookmarks(true)
        .resourceVersion(currentVersion)
        .buildCall(null), (new TypeToken<Watch.Response<V1Pod>>() {
}).getType())) {
    for (Watch.Response<V1Pod> response : watch) {
        //do something with the response
    }
}

Now whenever I receive a bookmark response, I get this exception:

java.lang.IllegalArgumentException: Expected the field `containers` to be an array in the JSON string but got `null`
	at io.kubernetes.client.openapi.models.V1PodSpec.validateJsonObject(V1PodSpec.java:1354)
	at io.kubernetes.client.openapi.models.V1Pod.validateJsonObject(V1Pod.java:280)
	at io.kubernetes.client.openapi.models.V1Pod$CustomTypeAdapterFactory$1.read(V1Pod.java:309)
	at io.kubernetes.client.openapi.models.V1Pod$CustomTypeAdapterFactory$1.read(V1Pod.java:299)
...

The line in the response body being parsed looks like this (but without the formatting):

{
  "type": "BOOKMARK",
  "object": {
    "kind": "Pod",
    "apiVersion": "v1",
    "metadata": {
      "resourceVersion": "241268288",
      "creationTimestamp": null
    },
    "spec": {
      "containers": null
    },
    "status": {}
  }
}

I can work around this problem by using the type parameter JsonObject instead of V1Pod but that is obviously not ideal. I'd be happy to contribute a PR to (help) fix this problem, but I wouldn't really know where to start.

jbruinink avatar Sep 30 '24 05:09 jbruinink

I encountered this error when executing io.kubernetes.client.openapi.apis.CoreV1Api#listNode against minikube.

The root cause is when the node's image list contains images that no-longer have a name. I.e. a new image has been pushed that has replaced an old image and re-used the name. I.e. the example shown in https://github.com/kubernetes-client/java/issues/3319#issuecomment-2058404461

The validation of the payload is overly strict in this case: there exist entirely valid ways to "orphan" images in a registry that supports mutable image names.

I'm not entirely convinced that an API client has the authority to determine the validity of an API server's list of images, especially when it does so with a fatal runtime exception, particularly when the node's image list may not even be relevant to the consumer of the node list.

nickbreen avatar Oct 23 '24 04:10 nickbreen

create watch with bookmark generates: ava.lang.IllegalArgumentException: Expected the field containers to be an array in the JSON string but got null

sconstro avatar Oct 29 '24 15:10 sconstro

I experience the same issue with k3s v1.29.7+k3s1.

TimoBuechert avatar Nov 11 '24 10:11 TimoBuechert

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

k8s-triage-robot avatar Dec 11 '24 11:12 k8s-triage-robot

@k8s-triage-robot: Closing this issue, marking it as "Not Planned".

In response to this:

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

k8s-ci-robot avatar Dec 11 '24 11:12 k8s-ci-robot

I believe that the problem still exists.

Informers with bookmarks enabled are somewhat unusable in Java because of the validation failures: the logic inside ReflectorRunnable uses watch.next which tries parsing the payload to the ApiType chosen w/o checking the event type.

shirolimit avatar Dec 13 '24 12:12 shirolimit