Port is open but getting connect timed out

host=www.example-api.com
port=443
while true; do
    current_time=$(date +%H:%M:%S)
    r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
    if [ "$r" = "0" ]; then
        echo "[$current_time] $host $port is open" >> log_file.txt
    else
        echo "[$current_time] $host $port is closed" >> log_file.txt
    fi
done

connect timed out; nested exception is org.apache.http.conn.ConnectTimeoutException

This is the exact error that I'm getting. My last resort is to extend the connection timeout.

Scenario:
Our application was getting the above mentioned error. That's why I put the following bash script on a cronjob in order to test if that's actually happening or not. I was surprised to find out that port was actually open although such errors were being received. That led me to the suspicion that I now need to increase the connection timeout.

Hello,

It would seem that you've been able to prove that, at the same time your application is getting an error saying its HTTP/HTTPS connection timed out, your Bash script is able to connect to that same endpoint successfully. So that at least tells you that the connection itself is not likely to be timing out.

Now, it should be noted that there is a difference here: your Bash script is simply checking that the port is open, and that will almost always be a success if there is genuinely something listening at the other end. That however doesn't tell you anything about how long it would take to get a meaningful response from that something, whatever it may be. Bash here is purely checking that it can establish a TCP connection to port 443 on the remote hostname, and if it does, then the exit status will be 0. No actual HTTP or HTTPS request is being made by Bash, this is purely a socket connection check and nothing else. The application at the remote server could indeed still be timing out, even under these circumstances.

So, it would be useful would be to try to get a log of whatever response, if any, your application is actually getting from the remote server. Or alternatively, if the application cannot easily be modified to provide such debugging info, to modify your Bash script to make a valid wget or curl request to the endpoint, and to log the response it gets back and how long it takes it to get it.

Hope this helps !

2 Likes

@drysdalk has raised some very valid points.
Not that it matters in the wrong run, but I'd modify your script at least this much:

#!/bin/bash
host='www.example-api.com'
port='443'

while : ; do
    current_time="$(date +%H:%M:%S)"
    r=$(bash -c "exec 3<> /dev/tcp/$host/$port;echo $?"  2>/dev/null)
    {
    if [ "$r" -eq 0 ]; then
        echo "[$current_time] $host $port is open"
    else
        echo "[$current_time] $host $port is closed" 
    fi
    } >> log_file.txt
done

You've a better Idea for a script? Using curl is really not sure if I get timely response.

Connection timeout usually means that client opened a connection to your web server and did nothing for long period of time.
Or request you made did not get a timely response e.g request sent takes too long to get a response - above TCP or apache timeout parameters.
Also, check your server metrics, if it under heavy load at mentioned timeout error.

Idle connections get closed if not used, since connections doing nothing are just taking ports for no reason.

Bash would not diagnose such failures as mentioned in post by drysdalk, only real request using curl or program using libcurl.

So you need to make a real request using libcurl program or curl, and see what happens on server side.
By real i mean the exact request which does GET or POST with data involved, not just hitting base example.com

Regards
Peasant.

It has been observed that the request hasn't been sent to the server by client. (Client is also a server for other clients).

The issue is now resolved. Traffic was trying to get pass from a tunnel which wasn't supposed to be accepted if another tunnel was open. Weird.

1 Like