{"record":{"id":"22156780e75f8e0f","repo":"gohugoio/hugo","slug":"retry-timeout-configured-to-s-fetching-remote-r","errorCode":null,"errorMessage":"retry timeout (configured to %s) fetching remote resource: %s","messagePattern":"retry timeout \\(configured to (.+?)\\) fetching remote resource: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/resource_factories/create/remote.go","lineNumber":515,"sourceCode":"\n\t\tif retry {\n\t\t\tsleep := nextSleep\n\t\t\tretryAfter := parseRetryAfter(resp)\n\t\t\tif retryAfter > 0 {\n\t\t\t\tsleep = retryAfter\n\t\t\t}\n\t\t\tif start.IsZero() {\n\t\t\t\tstart = time.Now()\n\t\t\t}\n\t\t\tif d := time.Since(start) + sleep; d >= t.Cfg.Timeout() {\n\t\t\t\tmsg := \"<nil>\"\n\t\t\t\tif resp != nil {\n\t\t\t\t\tmsg = resp.Status\n\t\t\t\t}\n\t\t\t\tif retryAfter > 0 {\n\t\t\t\t\tmsg = fmt.Sprintf(\"%s (server requested Retry-After: %s)\", msg, retryAfter)\n\t\t\t\t}\n\t\t\t\terr := toHTTPError(fmt.Errorf(\"retry timeout (configured to %s) fetching remote resource: %s\", t.Cfg.Timeout(), msg), resp, req.Method != \"HEAD\", nil)\n\t\t\t\treturn resp, err\n\t\t\t}\n\t\t\ttime.Sleep(sleep)\n\t\t\tif nextSleep < nextSleepLimit {\n\t\t\t\tnextSleep *= 2\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\treturn\n\t}\n}\n\n// We need to send the redirect responses back to the HTTP client from RoundTrip,\n// but we don't want to cache them.\nfunc shouldCache(statusCode int) bool {\n\tswitch statusCode {\n\tcase http.StatusMovedPermanently, http.StatusFound, http.StatusSeeOther, http.StatusTemporaryRedirect, http.StatusPermanentRedirect:","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/resources/resource_factories/create/remote.go#L497-L533","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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).","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."],"exampleFix":"# hugo.toml -- before\nhttpTimeout = \"10s\"\n\n# after\nhttpTimeout = \"60s\"","handlingStrategy":"retry","validationCode":"// Estimate retry budget against provider's typical 5xx/429 behaviour before building.\n// If provider SLA needs > Hugo timeout, pre-fetch outside the build.","typeGuard":null,"tryCatchPattern":"// Build-level retry with backoff for known-flaky upstreams.\nfor i := 0; i < 3; i++ {\n\tif err := hugoBuild(); err == nil { break }\n\tif !isRetryTimeoutErr(err) { break }\n\ttime.Sleep(time.Duration(i+1) * time.Minute)\n}","preventionTips":["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."],"tags":["resources","remote","http","retry","timeout","network"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}