dbt-labs/dbt-core · error · anyhow
upload {filename} failed: {status} {body}
Error message
upload {filename} failed: {status}
{body} What it means
This error is raised by upload_dist in crates/dbt-ci/src/publish.rs when an artifact upload (to CodeArtifact or PyPI) fails with a non-success HTTP status that is not recognized as an 'already exists' condition, after all retry attempts for transient failures are exhausted. The bail includes the HTTP status and the response body so the developer can see the registry's actual rejection reason.
Source
Thrown at crates/dbt-ci/src/publish.rs:435
return Ok(());
}
if status.is_server_error() && attempt < max_attempts {
let delay = backoff(attempt);
eprintln!(
"warning: upload attempt {attempt}/{max_attempts} for {filename} got {status}; retrying in {}ms",
delay.as_millis(),
);
tokio::time::sleep(delay).await;
continue;
}
let body = resp.text().await.unwrap_or_default();
if is_already_exists(status, &body) {
eprintln!(
"• {filename} already published at {url}; treating as success ({status})"
);
return Ok(());
}
bail!("upload {filename} failed: {status}\n{body}");
}
Err(e) if is_transient(&e) && attempt < max_attempts => {
let delay = backoff(attempt);
eprintln!(
"warning: upload attempt {attempt}/{max_attempts} for {filename} failed: {e}; retrying in {}ms",
delay.as_millis(),
);
tokio::time::sleep(delay).await;
continue;
}
Err(e) => {
return Err(anyhow::Error::new(e).context(format!("POST {url}")));
}
}
}
}
fn build_upload_form(View on GitHub (pinned to 0267ce9170)
Solutions
- Inspect the status and body in the message: 401/403 means refresh registry credentials (e.g. aws codeartifact login or pip keyring auth) before retrying.
- If the version already exists but wasn't detected as such, bump the version or fix is_already_exists patterns to match your registry's duplicate message.
- Retest connectivity/proxy settings if the status is 5xx or a gateway error.
- Verify the artifact itself (correct filename, complete wheel/sdist) matches what the registry expects for the project name and version.
Example fix
// before
upload_dist(...).unwrap();
// after
if let Err(e) = upload_dist(...) {
eprintln!("publish failed (check registry auth/version): {e:#}");
std::process::exit(1);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: check auth + duplicate status before a long publish run
fn preflight_publish(registry: &str, version: &str) -> anyhow::Result<()> {
anyhow::ensure!(!version.is_empty(), "version required");
// verify credentials early, e.g. `aws codeartifact get-authorization-token` or `twine check`
Ok(())
} Try / catch
match upload_dist(...) {
Ok(()) => {},
Err(e) if e.to_string().contains("upload") => {
eprintln!("registry rejected upload, check auth/status: {e:#}");
std::process::exit(1);
}
Err(e) => return Err(e),
} Prevention
- Refresh registry credentials (codeartifact login / keyring) before release jobs.
- Bump the version for every publish; never republish an existing version.
- Ensure uploads happen after all build steps so artifacts are complete.
- Monitor the printed status/body to distinguish auth vs. duplicate vs. transient problems.
When it happens
Trigger: Calling upload_codeartifact or upload_pypi with a file whose upload request returns a 4xx/5xx status (e.g. 401 unauthorized, 403 forbidden, 400 bad request) that is not matched by is_already_exists, and where the error is not transient or retries are exhausted.
Common situations: Expired or missing registry credentials, uploading a package version that is rejected (immutable version, name mismatch), network/proxy failures that are non-transient, or the registry rejecting a malformed artifact (e.g. wrong filename or broken twine metadata).
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- GET {url} failed: {status}
- failed to download {url}: {last}
- `http_status_as_error` is not enabled.
- POST {url}
- GET {url}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/ec980105b2252fb1.
Report an issue: GitHub.