You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I built the Spring application as a Docker image and completed testing locally. I confirmed that the OpenAI API communication was successful and the response was received properly. Afterward, I deployed the application to the production environment. However, I encountered an error as mentioned above, and the IOException error message returned null, making it difficult to identify the cause.
I have verified that the OpenAI API key is correct, and I confirmed that there are no issues with the HTTPS reverse proxy settings on the Caddy web server. However, when checking the OpenAI API dashboard, I found that the requests were not reaching it, as the count was not increasing. I also discovered that an IOException exception was occurring in the DefaultRestClient during the request generation in the Spring application. At this point, I couldn't determine the cause and decided to register the issue. I will provide additional information if needed.
Build the Spring application as a Docker image and test it locally to confirm that OpenAI API communication is working correctly and the response is received.
Deploy the application to the production environment.
Get the error logs, which show an IOException error. Many Timeout cases are observed, and the requests are not reaching the OpenAI API as confirmed by the dashboard.
@ConfigurationpublicclassOpenAiConfiguration {
@Value("${spring.ai.openai.api-key}")
privateStringopenAiApiKey;
@BeanpublicOpenAiApiopenAiApi() {
returnnewOpenAiApi(getApiKey());
}
privateStringgetApiKey() {
StringapiKey = openAiApiKey;
if (!StringUtils.hasText(apiKey)) {
thrownewIllegalArgumentException(
"You must provide an API key. Put it in an environment variable under the name OPENAI_API_KEY");
}
returnapiKey;
}
@BeanpublicOpenAiChatModelopenAiChatModel(OpenAiApiapi) {
OpenAiChatModelopenAiChatModel = newOpenAiChatModel(api);
returnopenAiChatModel;
}
@BeanpublicRestClientCustomizerrestClientCustomizer() {
returnrestClientBuilder -> restClientBuilder
.requestFactory(ClientHttpRequestFactories.get(ClientHttpRequestFactorySettings.DEFAULTS
.withConnectTimeout(Duration.ofSeconds(30))
.withReadTimeout(Duration.ofSeconds(20))
));
}
}
I created the RestController form structure through classes like the one above, and the OpenAI API request is made by calling the request function of the ChatClientProvider class.
The above is the Caddy web server configuration file. After that, I opened ports 80 and 443 for inbound and outbound settings on the Oracle instance.
Stack Trace
2025-02-26T08:02:55.483Z WARN 1 --- [class-review-vilification] [nio-8080-exec-5] o.springframework.ai.retry.RetryUtils : Retry error. Retry count:1
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://api.openai.com/v1/chat/completions": null
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.createResourceAccessException(DefaultRestClient.java:534) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:459) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:424) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.ai.openai.api.OpenAiApi.chatCompletionEntity(OpenAiApi.java:256) ~[spring-ai-openai-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$1(OpenAiChatModel.java:274) ~[spring-ai-openai-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) ~[spring-retry-2.0.4.jar!/:na]
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209) ~[spring-retry-2.0.4.jar!/:na]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$3(OpenAiChatModel.java:274) ~[spring-ai-openai-1.0.0-M6.jar!/:1.0.0-M6]
at io.micrometer.observation.Observation.observe(Observation.java:565) ~[micrometer-observation-1.12.0.jar!/:1.12.0]
at org.springframework.ai.openai.OpenAiChatModel.internalCall(OpenAiChatModel.java:271) ~[spring-ai-openai-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.openai.OpenAiChatModel.call(OpenAiChatModel.java:255) ~[spring-ai-openai-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$1.aroundCall(DefaultChatClient.java:680) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextAroundCall$1(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at io.micrometer.observation.Observation.observe(Observation.java:565) ~[micrometer-observation-1.12.0.jar!/:1.12.0]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextAroundCall(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor.aroundCall(SimpleLoggerAdvisor.java:99) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextAroundCall$1(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at io.micrometer.observation.Observation.observe(Observation.java:565) ~[micrometer-observation-1.12.0.jar!/:1.12.0]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextAroundCall(DefaultAroundAdvisorChain.java:98) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetChatResponse(DefaultChatClient.java:493) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatResponse$1(DefaultChatClient.java:482) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at io.micrometer.observation.Observation.observe(Observation.java:565) ~[micrometer-observation-1.12.0.jar!/:1.12.0]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatResponse(DefaultChatClient.java:482) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetChatResponse(DefaultChatClient.java:466) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.chatResponse(DefaultChatClient.java:510) ~[spring-ai-core-1.0.0-M6.jar!/:1.0.0-M6]
at com.example.classreviewvilification.ChatClientProvider.request(ChatClientProvider.java:33) ~[!/:0.0.1-SNAPSHOT]
at com.example.classreviewvilification.api.PromptRequestEndPoint.request(PromptRequestEndPoint.java:25) ~[!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:254) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:182) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.1.jar!/:6.1.1]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.16.jar!/:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.16.jar!/:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.net.ConnectException: null
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:573) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123) ~[java.net.http:na]
at org.springframework.http.client.JdkClientHttpRequest.executeInternal(JdkClientHttpRequest.java:94) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:70) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) ~[spring-web-6.1.1.jar!/:6.1.1]
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:453) ~[spring-web-6.1.1.jar!/:6.1.1]
... 75 common frames omitted
Caused by: java.net.ConnectException: null
at java.net.http/jdk.internal.net.http.common.Utils.toConnectException(Utils.java:1047) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:198) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.AsyncSSLConnection.connectAsync(AsyncSSLConnection.java:56) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.Http2Connection.createAsync(Http2Connection.java:378) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.Http2ClientImpl.getConnectionFor(Http2ClientImpl.java:128) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.ExchangeImpl.get(ExchangeImpl.java:93) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.Exchange.establishExchange(Exchange.java:343) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.Exchange.responseAsyncImpl0(Exchange.java:475) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.Exchange.responseAsyncImpl(Exchange.java:380) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.Exchange.responseAsync(Exchange.java:372) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.MultiExchange.responseAsyncImpl(MultiExchange.java:408) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsyncImpl$7(MultiExchange.java:449) ~[java.net.http:na]
at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:950) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2340) ~[na:na]
at java.net.http/jdk.internal.net.http.MultiExchange.responseAsyncImpl(MultiExchange.java:439) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsync0$2(MultiExchange.java:341) ~[java.net.http:na]
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1150) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773) ~[na:na]
at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:157) ~[java.net.http:na]
at java.base/java.util.concurrent.CompletableFuture.completeAsync(CompletableFuture.java:2673) ~[na:na]
at java.net.http/jdk.internal.net.http.MultiExchange.responseAsync(MultiExchange.java:294) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.HttpClientImpl.sendAsync(HttpClientImpl.java:654) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:552) ~[java.net.http:na]
... 80 common frames omitted
Caused by: java.nio.channels.UnresolvedAddressException: null
at java.base/sun.nio.ch.Net.checkAddress(Net.java:149) ~[na:na]
at java.base/sun.nio.ch.Net.checkAddress(Net.java:157) ~[na:na]
at java.base/sun.nio.ch.SocketChannelImpl.checkRemote(SocketChannelImpl.java:816) ~[na:na]
at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:839) ~[na:na]
at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$0(PlainHttpConnection.java:183) ~[java.net.http:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:569) ~[na:na]
at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:185) ~[java.net.http:na]
... 103 common frames omitted
Organize
I suspected that there might be an issue with SSL certificate management in the Caddy web server or requests without a specified host, but after seeing many Timeout cases among the IOException errors in the logs, I decided to raise this issue.
I have confirmed all OpenAI API permissions, and if any additional information is needed, please feel free to request it in the comments.
The text was updated successfully, but these errors were encountered:
I have found a solution. When I made OpenAI API requests using an Oracle Cloud EC2 instance hosted in the Osaka region, it produced those error stacks, but after switching to an EC2 instance in the Korean region, I confirmed that it worked normally without throwing any errors.
Could it be that the cloud service region is causing issues with the OpenAI API responses?
Bug description
I built the Spring application as a Docker image and completed testing locally. I confirmed that the OpenAI API communication was successful and the response was received properly. Afterward, I deployed the application to the production environment. However, I encountered an error as mentioned above, and the IOException error message returned null, making it difficult to identify the cause.
I have verified that the OpenAI API key is correct, and I confirmed that there are no issues with the HTTPS reverse proxy settings on the Caddy web server. However, when checking the OpenAI API dashboard, I found that the requests were not reaching it, as the count was not increasing. I also discovered that an IOException exception was occurring in the DefaultRestClient during the request generation in the Spring application. At this point, I couldn't determine the cause and decided to register the issue. I will provide additional information if needed.
Environment
EC2 Instance : Oracle Cloud
OS : Canonical Ubuntu 22.04
WebServer : Caddy
Steps to reproduce
Build the Spring application as a Docker image and test it locally to confirm that OpenAI API communication is working correctly and the response is received.
Deploy the application to the production environment.
Get the error logs, which show an IOException error. Many Timeout cases are observed, and the requests are not reaching the OpenAI API as confirmed by the dashboard.
Expected behavior
I expected to receive the normal response text from the endpoint https://api.openai.com/v1/chat/completions.
Minimal Complete Reproducible example
I created the RestController form structure through classes like the one above, and the OpenAI API request is made by calling the request function of the ChatClientProvider class.
Caddy Webserver config
/etc/systemd/system/caddy.service
/etc/caddy/Caddyfile
The above is the Caddy web server configuration file. After that, I opened ports 80 and 443 for inbound and outbound settings on the Oracle instance.
Stack Trace
Organize
I suspected that there might be an issue with SSL certificate management in the Caddy web server or requests without a specified host, but after seeing many Timeout cases among the IOException errors in the logs, I decided to raise this issue.
I have confirmed all OpenAI API permissions, and if any additional information is needed, please feel free to request it in the comments.
The text was updated successfully, but these errors were encountered: