Cookies management by TermsFeed Cookie Consent

📡 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.


Thank you for being on our site 😊. If you like our tutorials and examples, please consider supporting us with a cup of coffee and we'll turn it into more great Go examples.

Have a great day!

Buy Me A Coffee

🔌 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