Cookies management by TermsFeed Cookie Consent
Russia has invaded Ukraine and already killed tens of thousands of civilians, with many more raped or tortured. It's a genocide. We need your help. Let's fight back against the Russian regime.
Help Ukraine! Fight the Russian regime!

📡 Handle Context Deadline Exceeded error in Go

http errors

Please consider supporting us by disabling your ad blocker

Context Deadline Exceeded is an error occurring in Go when a context of an HTTP request has a deadline or a timeout set, i.e., the time after which the request should abort. This error is returned if the time of a server response is greater than the set timeout. Setting timeouts on requests is a good practice in a production environment to ensure that you always get a response (or error) in a finite time.

Context deadline exceeded example

    package main

    import (
        "context"
        "errors"
        "log"
        "net/http"
        "os"
        "time"
    )

    func slowServer(w http.ResponseWriter, r *http.Request) {
        time.Sleep(10 * time.Second)
        w.Write([]byte("Hello world!"))
    }

    func call() error {
        client := &http.Client{}
        req, err := http.NewRequest(http.MethodGet, "http://localhost:8080", nil)
        if err != nil {
            return err
        }
        ctx, cancel := context.WithTimeout(req.Context(), 1*time.Second)
        defer cancel()
        req = req.WithContext(ctx)
        _, err = client.Do(req)
        return err
    }

    func main() {
        // run slow server
        go func() {
            http.HandleFunc("/", slowServer)

            if err := http.ListenAndServe(":8080", nil); err != nil {
                log.Fatal(err)
            }
        }()

        time.Sleep(1 * time.Second) // wait for server to run

        // call server
        err := call()
        if errors.Is(err, context.DeadlineExceeded) {
            log.Println("ContextDeadlineExceeded: true")
        }
        if os.IsTimeout(err) {
            log.Println("IsTimeoutError: true")
        }
        if err != nil {
            log.Fatal(err)
        }
    }

Output:

2021/08/19 06:39:09 ContextDeadlineExceeded: true
2021/08/19 06:39:09 IsTimeoutError: true
2021/08/19 06:39:09 Get "http://localhost:8080": context deadline exceeded
exit status 1

In the example above, we:

Since a timeout for this request is set to 1 second and the server responds after 10 seconds, the HTTP client returns an error.

Handle Context deadline exceeded error

An HTTP client returns the context.DeadlineExceeded error when the set timeout is exceeded. This error can also be handled with the more general os.IsTimeout() function that checks if the error is known to report that a timeout occurred.

Context deadline exceeded (Client.Timeout exceeded while awaiting headers) example

The timeout can be set not only at the level of a single HTTP request but also at the level of the entire HTTP client. In this case, each request made by such a client has the same timeout value. See the example of a call() function using the client timeout option:

func call() error {
    client := &http.Client{Timeout: 1 * time.Second}
    _, err := client.Get("http://localhost:8080")
    return err
}

Output:

2021/08/19 07:35:14 IsTimeoutError: true
2021/08/19 07:35:14 Get "http://localhost:8080": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
exit status 1

In this case, we get the context deadline exceeded (Client.Timeout exceeded while awaiting headers) error. Note that this is not an instance of context.DeadlineExceeded error.

🔌 Handle 'connection reset by peer' error in Go

Learn what it means and how to detect the 'connection reset by peer' error
http errors

🪠 Handle 'broken pipe' error in Go

Learn how to detect the 'broken pipe' error when writing an HTTP response
http errors

📔 Convert a struct to io.Reader in Go

Learn how to convert a struct to io.Reader and send it as an HTTP POST request body
introduction http