kubernetes-client / java

Official Java client library for kubernetes
http://kubernetes.io/
Apache License 2.0
3.55k stars 1.89k forks source link

ApiException cause or message is blank #2066

Closed MissakaI closed 6 months ago

MissakaI commented 2 years ago

Describe the bug I am trying to create a statefulset using AppsV1Api and it throws a ApiException with no cause to identify what the issue is.

Compete Stacktrace as follows:

2022-01-05 19:29:43.150 ERROR 1 --- [-nio-80-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is io.kubernetes.client.openapi.ApiException: ] with root cause

io.kubernetes.client.openapi.ApiException: 
        at io.kubernetes.client.openapi.ApiClient.handleResponse(ApiClient.java:973) ~[client-java-api-14.0.0.jar!/:na]
        at io.kubernetes.client.openapi.ApiClient.execute(ApiClient.java:885) ~[client-java-api-14.0.0.jar!/:na]
        at io.kubernetes.client.openapi.apis.AppsV1Api.createNamespacedStatefulSetWithHttpInfo(AppsV1Api.java:1119) ~[client-java-api-14.0.0.jar!/:na]
        at io.kubernetes.client.openapi.apis.AppsV1Api.createNamespacedStatefulSet(AppsV1Api.java:1084) ~[client-java-api-14.0.0.jar!/:na]
        at com.objectone.selenium.grid.k8s.dockerinterceptor.service.KubernetesManagementService.createPod(KubernetesManagementService.java:149) ~[classes!/:0.0.1-SNAPSHOT]
        at com.objectone.selenium.grid.k8s.dockerinterceptor.controller.NodeDockerContainerRequestController.create(NodeDockerContainerRequestController.java:29) ~[classes!/:0.0.1-SNAPSHOT]
        at jdk.internal.reflect.GeneratedMethodAccessor42.invoke(Unknown Source) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.13.jar!/:5.3.13]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar!/:5.3.13]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:769) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.55.jar!/:na]
        at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]

Client Version 14.0.0

Kubernetes Version 1.22.4 on Docker Desktop 4.3.1

Java Version Java 11

To Reproduce

    public ContainerCreateResponse createPod(ContainerCreateConfig containerCreateConfig) throws ApiException {
        ApiClient client = ClientBuilder.cluster().build();
        io.kubernetes.client.openapi.Configuration.setDefaultApiClient(client);

        AppsV1Api appsApi = new AppsV1Api(apiClient);

        String image = ImageSummary.getImageName(containerCreateConfig.getImage());

        String id = image.split(":")[0].replace("/","-")+
                UUID.randomUUID().toString();

        log.info("Requested Image: {}",image);

        V1ContainerBuilder containerBuilder = new V1ContainerBuilder()
                .withName("selenium")
                .withImage(image);

        if (containerCreateConfig.getEnv().length>0)
                containerBuilder.withEnv(
                        Arrays.stream(containerCreateConfig.getEnv())
                                .map(s -> {
                                    String[] env = s.split("=");
                                    return new V1EnvVar().name(env[0]).value(env[1]);
                                })
                                .collect(Collectors.toUnmodifiableList())
                );

        if (containerCreateConfig.getHostConfig().getPortBindings().size()>0)
                containerBuilder.withPorts(
                        containerCreateConfig.getHostConfig().getPortBindings().entrySet().stream()
                                .map(stringMapEntry -> {
                                    String[] containerPort = stringMapEntry.getKey().split("/");
                                    Integer hostPort = stringMapEntry.getValue().get("HostPort").asInt();
                                    return new V1ContainerPortBuilder()
                                            .withContainerPort(Integer.valueOf(containerPort[0]))
                                            .withProtocol(containerPort[1])
                                            .withHostPort(hostPort)
                                            .build();
                                })
                                .collect(Collectors.toUnmodifiableList())
                );

        if (containerCreateConfig.getHostConfig().getBinds().length>0)
                containerBuilder.withVolumeMounts(
                        Arrays.stream(containerCreateConfig.getHostConfig().getBinds())
                                .map(s -> {
                                    String[] bind = s.split(":");
                                    return new V1VolumeMount().mountPath(bind[0]).mountPropagation(bind[1]);
                                })
                                .collect(Collectors.toUnmodifiableList())
                );

        V1StatefulSet statefulSet = new V1StatefulSetBuilder()
                .withNewMetadata()
                    .withName(id)
                .endMetadata()
                .withNewSpec()
                    .withReplicas(1)
                    .withNewTemplate()
                        .withNewMetadata()
                            .withName("selenium")
                        .endMetadata()
                        .withNewSpec()
                            .withContainers(containerBuilder.build())
                        .endSpec()
                    .endTemplate()
                .endSpec()
                .build();

        appsApi.createNamespacedStatefulSet("default",statefulSet,null,null,null);

        return ContainerCreateResponse.builder().id(id).build();
    }

Expected behavior Either create the statefulset or throw an exception with proper message

2022-01-05 19:29:43.150 ERROR 1 --- [-nio-80-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is io.kubernetes.client.openapi.ApiException: <exception_message>] with root cause

io.kubernetes.client.openapi.ApiException: <exception_message>
        at io.kubernetes.client.openapi.ApiClient.handleResponse(ApiClient.java:973) ~[client-java-api-14.0.0.jar!/:na]
        at io.kubernetes.client.openapi.ApiClient.execute(ApiClient.java:885) ~[client-java-api-14.0.0.jar!/:na]

KubeConfig If applicable, add a KubeConfig file with secrets redacted.

Server (please complete the following information):

Additional context Tried it with a incorrect attempt to create a pod using CoreV1Api which resulted in an exception with no cause as well. And with a correct config it creates the pod with no issues at all. So that proves the kubernetes api is reachable and has proper access priviledges.

brendandburns commented 2 years ago

I don't think that this is a bug in the client. If you look at the place where the exception was thrown:

https://github.com/kubernetes-client/java/blob/master/kubernetes/src/main/java/io/kubernetes/client/openapi/ApiClient.java#L973

It is setting response.message() to be the message for the exception. For some reason the server that you are talking to is returning an empty status line in it's HTTP response. I think you will need to debug your server for more information.

You can try printing APIException.getCode() or APIException.getResponseBody() to get more details from the exception that may help with this debugging.

MissakaI commented 2 years ago

You can try printing APIException.getCode() or APIException.getResponseBody() to get more details from the exception that may help with this debugging.

Thanks for the tip on ability to print the response body using APIException.getResponseBody(). So this is one of output I got when i printed the response body.

{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"StatefulSet.apps \"selenium-standalone-firefox04699455\" is invalid: [spec.selector: Required value, spec.template.metadata.labels: Invalid value: map[string]string(nil): `selector` does not match template `labels`]","reason":"Invalid","details":{"name":"selenium-standalone-firefox04699455","group":"apps","kind":"StatefulSet","causes":[{"reason":"FieldValueRequired","message":"Required value","field":"spec.selector"},{"reason":"FieldValueInvalid","message":"Invalid value: map[string]string(nil): `selector` does not match template `labels`","field":"spec.template.metadata.labels"}]},"code":422}

In the response the message field is present. But still the ApiException stacktrace doesn't print the message.

brendandburns commented 2 years ago

fwiw, the message field in the Status response is unrelated to the message that is passed to the exception.

The message passed to the ApiException is an okhttp.Response.message so I still suspect that this is because the HTTP status message coming back from the server is empty.

If you look at the ApiException code there's no way that the response body can get set w/o also passing in a message to the exception.

Can you try printing ApiException.getMessage() explicitly and see what it prints?

MissakaI commented 2 years ago

As you suggested ApiException.getMessage() function worked. It printed the returned message field in the previously attached response body.

abelsromero commented 2 years ago

We are struggling with similar scenario but we cannot call methods since errors occur during startup via Spring configuration for example. We end up with simple io.kubernetes.client.openapi.ApiException: with no info, for example could be for lack of permissions for the service account or API not available in some cloud provider/k8s version, but it's not possible to know. Would it make sense (even if under some config flag) to add the response body to the message so it's shown by default.

stevenschlansker commented 2 years ago

We are running into this problem as well - ApiException is thrown with a null message, and the inherited Exception.toString method does not know about the responseBody, so it does not get printed and all you see is ApiException: null which is extremely unhelpful.

abelsromero commented 2 years ago

I run into the same thing today, and resorted to making a custom build of the client adding this to ApiException (btw, kudos for how easy it was, mvn package and done!).

  @Override
  public String getMessage() {
    String code = String.valueOf(getCode());
    return code + getResponseBody();
  }

With that I went from

2022-03-23 17:32:02.999 ERROR 1 --- [-lease-worker-1] i.k.c.e.leaderelection.LeaderElector     : Error retrieving resource lock spring-cloud-gateway/configmap-reconciler

io.kubernetes.client.openapi.ApiException:
    at io.kubernetes.client.openapi.ApiClient.handleResponse(ApiClient.java:974) ~[na:na]
    at io.kubernetes.client.openapi.ApiClient.execute(ApiClient.java:886) ~[na:na]
    at io.kubernetes.client.openapi.apis.CoordinationV1Api.readNamespacedLeaseWithHttpInfo(CoordinationV1Api.java:2743) ~[na:na]

to

2022-03-23 17:37:39.518 ERROR 1 --- [-lease-worker-1] i.k.c.e.leaderelection.LeaderElector     : Error retrieving resource lock spring-cloud-gateway/configmap-reconciler

io.kubernetes.client.openapi.ApiException: 403{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"leases.coordination.k8s.io \"configmap-reconciler\" is forbidden: User \"system:serviceaccount:test:default\" cannot get resource \"leases\" in API group \"coordination.k8s.io\" in the namespace \"spring-cloud-gateway\"","reason":"Forbidden","details":{"name":"configmap-reconciler","group":"coordination.k8s.io","kind":"leases"},"code":403}

    at io.kubernetes.client.openapi.ApiClient.handleResponse(ApiClient.java:974) ~[client-java-api-13.0.3.jar:na]
    at io.kubernetes.client.openapi.ApiClient.execute(ApiClient.java:886) ~[client-java-api-13.0.3.jar:na]

I am not argueing this is trivial and should be done based on code lines count, we should probably sanitize the output and account for many more things. But I hope this exemplifies the struggles of not having any information when an error happens and you are not the one calling the API directly. Now I know I forgot to correctly setup the service account 🤦

Maybe we can start a conversation on a approach?

nodejh commented 2 years ago

I run into the same issue too.

I can't get some important information about the problem, because the ApiException#message is null when an exception occurs during leader election.

I create a CustomLeaderElector class which copy from io.kubernetes.client.extended.leaderelection.LeaderElector and overwrite tryAcquireOrRenew() method to print more message of ApiException, finally, I find my problem from the ResponseBody.

public class CustomLeaderElector {
  // ...
  private boolean tryAcquireOrRenew() {
        // ...
        try {
            oldLeaderElectionRecord = lock.get();
        } catch (ApiException var6) {

           // print more message of ApiException
            log.error("tryAcquireOrRenew ApiException, code: {}, message: {}, header: {}, response: {}", var6.getCode(), var6.getMessage(), var6.getResponseHeaders(), var6.getResponseBody());

            if (var6.getCode() != 404) {
                log.error("Error retrieving resource lock {}", lock.describe(), var6);
                return false;
            }
    }
}

Log:

[2022-06-16 17:56:05.464] [ERROR] [leader-elector-lease-worker-1] com.aliyun.actiontrail.client.CustomLeaderElector tryAcquireOrRenew:233 - tryAcquireOrRenew ApiException, code: 403, message: , header: {audit-id=[3316d6ae-1619-4676-8132-ecbbbacb0579], cache-control=[no-cache, private], content-length=[427], content-type=[application/json], date=[Thu, 16 Jun 2022 09:56:05 GMT], x-content-type-options=[nosniff], x-kubernetes-pf-flowschema-uid=[6373319d-163d-483f-98c5-e8b80c0cd018], x-kubernetes-pf-prioritylevel-uid=[8aadd4ee-cb09-40c3-9b4b-814d2b7d4b38]}, response: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"leases.coordination.k8s.io \"xxx\" is forbidden: User \"system:serviceaccount:xx-service:default\" cannot get resource \"leases\" in API group \"coordination.k8s.io\" in the namespace \"xx-service\"","reason":"Forbidden","details":{"name":"xxx,"group":"coordination.k8s.io","kind":"leases"},"code":403}

The ApiException#message is null and the ApiException#responseBody#message is not null, but we can't get responseBody in stack trace. So I think it would be better to add correct error message in ApiException#message.

k8s-triage-robot commented 2 years ago

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

This bot triages issues and PRs according to the following rules:

You can:

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

/lifecycle stale

aespinosa commented 2 years ago

fwiw, the message field in the Status response is unrelated to the message that is passed to the exception.

For some reason the Response#message() being passed is proably null? It's supposed to be an string interpretation of the HTTP Status code based on https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response/. Maybe we can inspect the response object prior to the ApiException being code inside a debugger and isolate it into an OkHttp bug?

aespinosa commented 2 years ago

in practice, i liked setting ApiClient#setDebugging(true) to workaround the lack of verbosity in ApiException when trying to reproduce issues.

k8s-triage-robot commented 1 year ago

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

This bot triages issues and PRs according to the following rules:

You can:

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

/lifecycle rotten

stevenschlansker commented 1 year ago

Turns out, if there is no change, the issue doesn't just magically solve itself, no matter what the bot wants.

/remove-lifecycle stale

stevenschlansker commented 1 year ago

oops...

/remove-lifecycle rotten

brendandburns commented 1 year ago

fwiw, I did actually notice that there is a constructor where the response body can be set without the message getting set:

https://github.com/kubernetes-client/java/blob/master/kubernetes/src/main/java/io/kubernetes/client/openapi/ApiException.java#L58

We may need an upstream fix in the client generator to fix this.

k8s-triage-robot commented 1 year ago

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

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

You can:

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

/lifecycle stale

stevenschlansker commented 1 year ago

/remove-lifecycle stale

k8s-triage-robot commented 1 year ago

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

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

You can:

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

/lifecycle stale

stevenschlansker commented 1 year ago

We are still affected by this. What will it take to get some attention here? Serviceability is very important for having Kubernetes be a usable platform. I would be happy to file a PR, but it looked like the above fix was too surface level to be the right fix, and it is not likely that a community member will be able to step up and push through a fix to a code generator...

/remove-lifecycle stale

SheldonXLD commented 1 year ago

when create k8s apiclient, please try to set http protocol to http 1.1

k8s-triage-robot commented 8 months ago

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

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

You can:

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

/lifecycle stale

k8s-triage-robot commented 7 months ago

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:

You can:

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

/lifecycle rotten

jamietanna commented 7 months ago

/remove-lifecycle stale

k8s-triage-robot commented 6 months ago

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:

You can:

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

/close not-planned

k8s-ci-robot commented 6 months ago

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

In response to [this](https://github.com/kubernetes-client/java/issues/2066#issuecomment-2015225234): >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][1] > >Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community). > >/close not-planned > >[1]: https://www.kubernetes.dev/docs/guide/issue-triage/ Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.