If you work with MuleSoft applications, you know the specific pain of seeing a request fail when you are absolutely certain the URL is correct. One of the most common and frustrating hiccups is the "Remotely Closed" error during HTTP POST requests.
This typically occurs when the Mule Runtime is under heavy load. While it is a common connectivity issue, it is entirely fixable. In this guide, we will break down the root cause using simple analogies and provide three specific configuration strategies to stabilize your flows.
The Symptom: HTTP:CONNECTIVITY Failure
You are running a standard HTTP POST request. Suddenly, your logs throw an HTTP:CONNECTIVITY error. It usually looks exactly like the stack trace below:
Message : HTTP POST on resource 'http://10.164.112.16:8081/emp' failed: Remotely closed.
Element : empCreate/processors/3/processors/0 @ my-emp-app:emp-create.xml:129 (Request)
Error type : HTTP:CONNECTIVITY
Root Exception stack trace:
java.io.IOException: Remotely closed
What Causes the "Remotely Closed" Error?
To understand this, think of making a telephone call. You pick up the line to dial, but you realize the person on the other end has already hung up.
By default, Mule 4’s HTTP Request utilizes "persistent connections." This is a performance feature that keeps a pool of open network connections ready to use so your application doesn't have to "dial the number" (handshake) for every single request.
Here is the catch:
- The Idle Timeout: If a connection sits idle for too long, the target server closes it to save its own resources.
- The Busy Runtime: If your Mule Runtime is processing a heavy load, it might not immediately realize that the server closed the connection.
- The Error: Mule tries to grab that "stale" connection from the pool to send a new request. Since the line is dead, the request fails immediately with "Remotely Closed."
The Problematic Scenario
In a simple flow, if the server kills a connection due to inactivity but Mule is too busy to clean up its pool, the very next request using that connection will fail.
Original Code Causing Issues:
<http:request method="POST" doc:name="Request" doc:id="fb5feefe-e753-41b7-a2dd-0b3f7f440051" config-ref="HTTP_Request_configuration" path="${http.request.path}"></http:request>
How to Prevent the Error
To fix this, we need to actively manage how Mule handles these connections. Below are the three most effective strategies.
1. Implement Retry Logic
Sometimes, a simple retry is the best defense. If the first attempt hits a stale connection and fails, the second attempt will usually spin up a fresh, valid connection. We use the Until Successful scope to automate this.
<until-successful objectStore-ref="objectStore">
<http:request ... /> </until-successful>
2. Reduce Connection Idle Timeout
The goal here is to make Mule drop the connection before the server does. By decreasing the connectionIdleTimeout in your configuration, you ensure Mule closes the line locally while it is still valid. This prevents the runtime from trying to reuse a dead line later.
<http:request-config name="HTTP_Request_configuration" ...>
<http:request-connection connectionIdleTimeout="5000" /> </http:request-config>
3. Reduce Maximum Connections
If you have too many open connections, managing them becomes difficult for the server. Limiting the maxConnections ensures you don't overload the server or the connection pool.
<http:request-config name="HTTP_Request_configuration" ...>
<http:request-connection maxConnections="20" connectionIdleTimeout="5000" /> </http:request-config>
The Complete Solution
Here is the detailed example combining all three strategies. We are limiting connections, setting a strict timeout, and wrapping the request in a retry scope for maximum stability.
Optimized Configuration:
<http:request-config name="HTTP_Request_configuration" ...>
<!-- Limiting connections to 20 and timeout to 5 seconds -->
<http:request-connection maxConnections="20" connectionIdleTimeout="5000" /></http:request-config><flow name="exampleFlow">
<!-- Retry logic handles intermittent failures -->
<until-successful objectStore-ref="objectStore">
<http:request method="POST" config-ref="HTTP_Request_configuration_pf" path="${http.request.path}">
<http:request-builder>
<http:header headerName="Content-Type" value="application/json"/>
</http:request-builder>
</http:request>
</until-successful></flow>
Summary of Settings
- maxConnections="20": Prevents overloading the pool.
- connectionIdleTimeout="5000": Closes idle connections every 5 seconds (promptly) so they don't become stale.
- until-successful: Automatically retries if a "Remotely Closed" error slips through.
By applying these settings, you ensure your HTTP communications remain stable even when the Runtime is under heavy load.