java: ApiException cause or message is blank

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):

  • OS: Windows 10
  • Environment: Executed within a container in the cluster.

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.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 3
  • Comments: 20 (8 by maintainers)

Commits related to this issue

Most upvoted comments

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.

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.