How to check for HTTP timeout errors in Go

A timeout is a time limit in which an operation must be completed. If the operation is not finished in the given time limit, a timeout occurs and the operation is canceled. This article will discuss how to specifically detect timeout errors in Go.

It is necessary to enforce timeouts on client connections on a production web server. Without timeouts, requests that get stuck or take a long time to complete can cause your server to run out of file descriptors which prevents it from accepting new connections, and you certainly don’t want that.

http: Accept error: accept tcp [::]:80: accept: too many open files; retrying in 1s

Here’s a simple way to set timeouts for an HTTP request in Go:

client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get("https://freshman.tech")

The above snippet sets a timeout of 10 seconds on the HTTP client. So any request made with the client will timeout after 10 seconds if it does not complete in that time.

Before using the response from the request, you can check for a timeout error using the os.IsTimeout() method. It returns a boolean indicating whether the error is known to report a timeout that occurred.

client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(url)
if err != nil {
	if os.IsTimeout(err) {
		// A timeout error occurred
		return
	}

	// This was an error, but not a timeout
}

// use the response

Another method involves using the net.Error interface along with a type assertion, but I prefer os.IsTimeout() due to its simplicity.

client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Get(url)
if err, ok := err.(net.Error); ok && err.Timeout() {
	// A timeout error occurred
} else if err != nil {
	// This was an error, but not a timeout
}

If you know of any other tips regarding checking for HTTP timeouts in Go, please leave a comment below.

Thanks for reading, and happy coding!