📡 Handle Context Deadline Exceeded error in Go

http errors

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 Broken Pipe error in Go

Learn how to detect the Broken Pipe error when writing an HTTP response
http errors

🕵️ Solve 'cannot take address of XXX' error in Go

Learn how to take the address of a literal, map value, or function return value
introduction pointer errors

📂 Check if a file exists in Go

Learn how to check if a file exists in Go after or before opening it
introduction file errors