gohugoio/hugo · error
retry timeout (configured to ) fetching remote resource
Error message
retry timeout (configured to %s) fetching remote resource: %s
What it means
Returned by the custom `transport.RoundTrip` (remote.go:469-527) when the cumulative retry budget exceeds `Cfg.Timeout()`. The transport retries on transient status codes (408, 429, 500, 502, 503, 504) with exponential backoff, optionally honoring `Retry-After`. Once `time.Since(start) + nextSleep >= Timeout`, the loop aborts with this `*HTTPError` carrying the last response status and, if present, the server's `Retry-After` value.
Solutions
- Raise the global HTTP timeout: `httpTimeout = "60s"` (or higher) in hugo config; the configured value appears in the error message.
- Reduce the request rate or move the fetch off the critical build path (pre-fetch via a script, commit the asset).
- If 429, ensure `Retry-After` is honored (current Hugo does); contact the provider about quota.
- Retry the build outside the provider's peak window.
- Verify the endpoint is healthy via `curl -i` -- sustained 5xx may indicate a real outage, not a transient blip.
Example fix
# hugo.toml -- before httpTimeout = "10s" # after httpTimeout = "60s"
Defensive patterns
Strategy: retry
Validate before calling
// Estimate retry budget against provider's typical 5xx/429 behaviour before building. // If provider SLA needs > Hugo timeout, pre-fetch outside the build.
Try / catch
// Build-level retry with backoff for known-flaky upstreams.
for i := 0; i < 3; i++ {
if err := hugoBuild(); err == nil { break }
if !isRetryTimeoutErr(err) { break }
time.Sleep(time.Duration(i+1) * time.Minute)
} Prevention
- Tune `httpTimeout` to exceed the provider's worst-case retry window.
- Pre-fetch rate-limited resources via a scheduled script and commit locally.
- Build outside provider maintenance windows.
- Contact provider about quota for sustained 429s.
When it happens
Trigger: `resources.GetRemote` to an endpoint returning repeated 503/429 with the server's `Retry-After` exceeding Hugo's configured `httpTimeout`; or sustained 500/502 where exponential backoff accumulates past the budget. The error surfaces the last HTTP status so the caller can see what the server was saying.
Common situations: Upstream rate-limits (429) with a long `Retry-After`; overloaded origin returning 503 during deploy; CI build hitting a third-party API during its maintenance window; default `httpTimeout` too low for an endpoint that legitimately needs retries; missing `Retry-After` parsing bug leading to under-waiting (Hugo now parses it, but older builds didn't).
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- failed to fetch remote resource from
- failed to read remote resource
- failed to create request for resource
- failed to parse URL for resource
- failed to calculate hash
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/22156780e75f8e0f.
Report an issue: GitHub.
Appendix: source
Thrown at resources/resource_factories/create/remote.go:515
if retry {
sleep := nextSleep
retryAfter := parseRetryAfter(resp)
if retryAfter > 0 {
sleep = retryAfter
}
if start.IsZero() {
start = time.Now()
}
if d := time.Since(start) + sleep; d >= t.Cfg.Timeout() {
msg := "<nil>"
if resp != nil {
msg = resp.Status
}
if retryAfter > 0 {
msg = fmt.Sprintf("%s (server requested Retry-After: %s)", msg, retryAfter)
}
err := toHTTPError(fmt.Errorf("retry timeout (configured to %s) fetching remote resource: %s", t.Cfg.Timeout(), msg), resp, req.Method != "HEAD", nil)
return resp, err
}
time.Sleep(sleep)
if nextSleep < nextSleepLimit {
nextSleep *= 2
}
continue
}
return
}
}
// We need to send the redirect responses back to the HTTP client from RoundTrip,
// but we don't want to cache them.
func shouldCache(statusCode int) bool {
switch statusCode {
case http.StatusMovedPermanently, http.StatusFound, http.StatusSeeOther, http.StatusTemporaryRedirect, http.StatusPermanentRedirect:View on GitHub (pinned to 52c9bd7908)