gohugoio/hugo · error
retry timeout (configured to %s) fetching remote resource: %
Error message
retry timeout (configured to %s) fetching remote resource: %s
What it means
Hugo's resources.GetRemote retry loop gave up because the cumulative time spent retrying a remote fetch (elapsed plus the next planned sleep, including any server-sent Retry-After) reached the configured timeout. Hugo retries transient HTTP failures (429, 5xx) with exponential backoff, and this error caps total retry time so a build doesn't hang on a misbehaving endpoint. The message includes the last HTTP status ('<nil>' if no response) and the server's Retry-After when present.
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 8a468df065)
Solutions
- Check the reported status: for 429, reduce fetch frequency or add authentication/tokens to raise the rate limit.
- Increase the timeout, e.g. in hugo.toml: [HTTPCache]... or the resource-getting timeout option (timeout = "2m") for resources.GetRemote via the options map: {timeout = "2m"}.
- Enable/configure the HTTP cache (caches / httpcache config) so repeated builds don't re-fetch the resource.
- Verify the URL is reachable from the build environment (CI egress, proxy settings).
- Wrap the fetch with try/with .Err handling in templates to fail gracefully: {{ with try (resources.GetRemote $url) }}...{{ end }}.
Example fix
// before (template)
{{ $r := resources.GetRemote "https://api.example.com/data.json" }}
// after: longer timeout + error handling
{{ $opts := dict "timeout" "2m" }}
{{ with try (resources.GetRemote "https://api.example.com/data.json" $opts) }}
{{ with .Err }}{{ warnf "%s" . }}{{ else }}{{ .Value.Content }}{{ end }}
{{ end }} Defensive patterns
Strategy: retry
Validate before calling
// config.toml — size timeout to the slowest expected endpoint
// [security.http] / resources.GetRemote options:
// {{ $opts := dict "responseHeaders" true }}
// timeout = "60s" # in [imaging]/site config: resourceGetRemote timeout via `timeout` key Try / catch
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}{{ warnf "remote fetch failed: %s" . }}{{ else }}{{ with .Value }}{{ .RelPermalink }}{{ end }}{{ end }}
{{ end }} Prevention
- Raise the `timeout` site config value for slow remote hosts
- Always check `.Err` on resources.GetRemote instead of using the result directly
- Cache remote resources (resources cache dir) so CI rebuilds don't refetch
- Prefer stable CDN URLs; avoid endpoints with rate limits
When it happens
Trigger: Calling resources.GetRemote (or css/js pipelines that fetch remote resources) against a URL that repeatedly returns retryable statuses (429/5xx) or errors, with total elapsed retry time + next sleep >= the timeout from security/httpcache config (default 1m). A server sending a Retry-After header longer than the remaining budget triggers it immediately.
Common situations: Rate-limited APIs (GitHub, font/CDN endpoints) returning 429 during CI builds with many parallel fetches; flaky or down remote hosts; a too-small custom timeout in site config; corporate proxies returning 503.
Related errors
- stopped after 10 redirects
- failed to read remote resource %q: %w
- failed to get remote ref %q: %w
- invalid timeout for resource %s: %w
- failed to fetch remote resource from '%s': %s
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/22156780e75f8e0f.json.
Report an issue: GitHub ↗.