{"record":{"id":"07d88503b585b15b","repo":"dbt-labs/dbt-core","slug":"get-url-failed-status","errorCode":null,"errorMessage":"GET {url} failed: {status}","messagePattern":"GET (.+?) failed: (.+?)","errorType":"http","errorClass":"anyhow","httpStatus":null,"severity":"error","filePath":"crates/dbt-ci/src/sdist.rs","lineNumber":222,"sourceCode":"        match http.get(url).send().await {\n            Ok(resp) => {\n                let status = resp.status();\n                if status.is_success() {\n                    return resp\n                        .bytes()\n                        .await\n                        .with_context(|| format!(\"read body from {url}\"));\n                }\n                if status.is_server_error() && attempt < max_attempts {\n                    let delay = backoff(attempt);\n                    eprintln!(\n                        \"warning: GET {url} got {status}; retrying in {}ms\",\n                        delay.as_millis()\n                    );\n                    tokio::time::sleep(delay).await;\n                    continue;\n                }\n                bail!(\"GET {url} failed: {status}\");\n            }\n            Err(e) if is_transient(&e) && attempt < max_attempts => {\n                let delay = backoff(attempt);\n                eprintln!(\n                    \"warning: GET {url} failed: {e}; retrying in {}ms\",\n                    delay.as_millis()\n                );\n                tokio::time::sleep(delay).await;\n                continue;\n            }\n            Err(e) => return Err(anyhow::Error::new(e).context(format!(\"GET {url}\"))),\n        }\n    }\n}\n\n/// Minimal pyproject wiring up the embedded backend; rich metadata lives in PKG-INFO.\nfn render_sdist_pyproject(spec: &Spec, version_pep440: &str) -> String {\n    let mut out = String::new();","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-ci/src/sdist.rs#L204-L240","documentation":"download in crates/dbt-ci/src/sdist.rs performs a GET of a wheel URL and retries transient failures with backoff; when it receives a final non-transient (or retry-exhausted) non-success HTTP status it bails with 'GET {url} failed: {status}'.","triggerScenarios":"build_release_sdist downloading a wheel whose GET returns 404 (wrong --download-base-url or missing artifact), 403 (private bucket/registry without credentials), or a persistent 5xx after retries are exhausted.","commonSituations":"Wheels not yet uploaded (publish order mistake), base URL typo or wrong S3/CodeArtifact path, expired presigned URLs or missing AWS credentials, CDN/proxy returning 5xx consistently.","solutions":["Check the status: 404 means fix --download-base-url or upload the wheels first; 403 means fix credentials/permissions for the artifact store.","Verify the exact URL in the message is reachable (curl -I) and that the wheel filename matches what was published.","Retry later if the status is a 5xx — transient cases are already retried internally, so persistent ones need infra attention.","Confirm network egress/proxy settings in CI allow reaching the host."],"exampleFix":"# before\nrelease-sdist build --download-base-url https://example.com/old-path ...\n# 404: wheel not there\n# after\nrelease-sdist build --download-base-url https://example.com/wheels/1.2.3 ...  # correct path with wheels uploaded first","handlingStrategy":"retry","validationCode":"# verify the wheel URL is reachable before the pipeline\nurl=\"$BASE_URL/$(basename \"$WHEEL\")\"\ncurl -fsIL \"$url\" >/dev/null || { echo \"cannot GET $url\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"match download(url).await {\n    Err(e) if e.to_string().starts_with(\"GET \") => {\n        eprintln!(\"wheel download failed permanently: {e:#}\");\n        std::process::exit(1); // inspect status: 404=wrong URL, 403=auth\n    }\n    r => r,\n}","preventionTips":["Publish wheels before building the sdist that references them.","Verify --download-base-url with curl -I before long release runs.","Keep presigned URLs/AWS credentials fresh for the duration of the job.","Rely on the built-in backoff for transient 5xx; treat persistent statuses as config problems."],"tags":["network","http","download"],"backgroundTag":"http-error-response","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}