diff --git a/clientutil/retry.go b/clientutil/retry.go
index 054d301607ea3575da8896e9110e39ada5fba3a2..3ca7b51a48289a18cd829947cbdbc400392ffc93 100644
--- a/clientutil/retry.go
+++ b/clientutil/retry.go
@@ -2,7 +2,6 @@ package clientutil
 
 import (
 	"errors"
-	"net"
 	"net/http"
 	"time"
 
@@ -18,14 +17,37 @@ func NewExponentialBackOff() *backoff.ExponentialBackOff {
 	return b
 }
 
-// Retry operation op until it succeeds according to the backoff policy b.
+// A temporary (retriable) error is something that has a Temporary method.
+type tempError interface {
+	Temporary() bool
+}
+
+type tempErrorWrapper struct {
+	error
+}
+
+func (t tempErrorWrapper) Temporary() bool { return true }
+
+// TempError makes a temporary (retriable) error out of a normal error.
+func TempError(err error) error {
+	return tempErrorWrapper{err}
+}
+
+// Retry operation op until it succeeds according to the backoff
+// policy b.
+//
+// Note that this function reverses the error semantics of
+// backoff.Operation: all errors are permanent unless explicitly
+// marked as temporary (i.e. they have a Temporary() method that
+// returns true). This is to better align with the errors returned by
+// the net package.
 func Retry(op backoff.Operation, b backoff.BackOff) error {
 	innerOp := func() error {
 		err := op()
 		if err == nil {
 			return err
 		}
-		if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
+		if tmpErr, ok := err.(tempError); ok && tmpErr.Temporary() {
 			return err
 		}
 		return backoff.Permanent(err)
@@ -33,7 +55,7 @@ func Retry(op backoff.Operation, b backoff.BackOff) error {
 	return backoff.Retry(innerOp, b)
 }
 
-var errHTTPBackOff = errors.New("temporary http error")
+var errHTTPBackOff = TempError(errors.New("temporary http error"))
 
 func isStatusTemporary(code int) bool {
 	switch code {
@@ -46,7 +68,8 @@ func isStatusTemporary(code int) bool {
 
 // RetryHTTPDo retries an HTTP request until it succeeds, according to
 // the backoff policy b. It will retry on temporary network errors and
-// upon receiving specific temporary HTTP errors.
+// upon receiving specific temporary HTTP errors. It will use the
+// context associated with the HTTP request object.
 func RetryHTTPDo(client *http.Client, req *http.Request, b backoff.BackOff) (*http.Response, error) {
 	var resp *http.Response
 	op := func() error {
@@ -64,6 +87,6 @@ func RetryHTTPDo(client *http.Client, req *http.Request, b backoff.BackOff) (*ht
 		return err
 	}
 
-	err := Retry(op, b)
+	err := Retry(op, backoff.WithContext(b, req.Context()))
 	return resp, err
 }