java icon indicating copy to clipboard operation
java copied to clipboard

ApiClient cannot deserialize responses larger than 2GB

Open klin1344 opened this issue 6 months ago • 7 comments
trafficstars

Describe the bug The ApiClient cannot handle responses larger than 2GB.

Client Version 22.0.1-legacy is what we're currently using, but this issue occurs in all versions

Kubernetes Version 1.30.9

Java Version Java 21

To Reproduce

  1. Set up a SharedIndexInformer for a resource in a cluster where the total size of all resources > 2GB.
  2. The initial list() in the ReflectorRunnable will fail with:
class io.kubernetes.client.openapi.models.V1Pod#Reflector loop failed unexpectedly

java.lang.IllegalArgumentException: byteCount: 2293832235
  at okio.Buffer.readString(Buffer.kt:306)
  at okio.Buffer.readString(Buffer.kt:302)
  at okio.RealBufferedSource.readString(RealBufferedSource.kt:96)
  at okhttp3.ResponseBody.string(ResponseBody.kt:187)
  at io.kubernetes.client.openapi.ApiClient.deserialize(ApiClient.java:758)
  at io.kubernetes.client.openapi.ApiClient.handleResponse(ApiClient.java:978)
  at io.kubernetes.client.openapi.ApiClient.execute(ApiClient.java:905)
  at io.kubernetes.client.informer.SharedInformerFactory$1.list(SharedInformerFactory.java:271)
  at io.kubernetes.client.informer.cache.ReflectorRunnable.run(ReflectorRunnable.java:91)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
  at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
  at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
  at java.lang.Thread.run(Thread.java:1583)

Expected behavior The ApiClient can deserialize responses greater than 2GB.

Additional context This issue occurs because the response body is converted to a String here in the ApiClient, which hits this validation in okhttp:

require(byteCount >= 0 && byteCount <= Integer.MAX_VALUE) { "byteCount: $byteCount" }

because of Java's String max length limit of Integer.MAX_VALUE which is 2^31 - 1.

klin1344 avatar Apr 21 '25 17:04 klin1344

https://github.com/kubernetes-client/java/blob/master/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java#L90-L92

The proper fix is to add pagination to the list call in the reflector..

yue9944882 avatar Apr 23 '25 17:04 yue9944882

https://github.com/kubernetes-client/java/blob/master/util/src/main/java/io/kubernetes/client/informer/cache/ReflectorRunnable.java#L90-L92

The proper fix is to add pagination to the list call in the reflector..

@yue9944882 Yes, we have already implemented a ListerWatcher that does pagination as a fix for our use case. However, similar to the official golang client pagination implementation, the ResourceVersion can expire mid-pagination, and the fallback mechanism is to do a full list.

Thus, pagination will help, but it is still necessary to support deserialization of a large response in case of a fallback.

klin1344 avatar Apr 23 '25 17:04 klin1344

https://github.com/OpenAPITools/openapi-generator/pull/21115 has merged, we'll pick this up in the next release.

Also @klin1344 if you wanted to commit the pagination support to our ListerWatcher that would be great.

brendandburns avatar Apr 24 '25 15:04 brendandburns

OpenAPITools/openapi-generator#21115 has merged, we'll pick this up in the next release.

Also @klin1344 if you wanted to commit the pagination support to our ListerWatcher that would be great.

@brendandburns Sure, the paginated ListerWatcher implementation is simpler than the one in the golang client right now, but I will still find some time to try to upstream it to this project.

klin1344 avatar Apr 30 '25 03:04 klin1344

PR to bump the openapi-generator version here https://github.com/kubernetes-client/gen/pull/280 so this gets picked up in the next release

klin1344 avatar May 02 '25 17:05 klin1344

Cool, do you want us to regenerate a patch release for this? Or are you willing to wait for the next Kubernetes version?

brendandburns avatar May 08 '25 15:05 brendandburns

@brendandburns Yes, if we could generate a patch release that would be great.

klin1344 avatar May 08 '25 16:05 klin1344

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 06 '25 16:08 k8s-triage-robot

This has been fixed with 24.0.0 which includes https://github.com/OpenAPITools/openapi-generator/pull/21115 and https://github.com/kubernetes-client/gen/pull/280 .

klin1344 avatar Aug 06 '25 16:08 klin1344