rust-lang/cargo · error
credential process ` ` failed with status
Error message
credential process `{}` failed with status {}` What it means
CredentialProcessCredential::run completes the JSON-over-stdio protocol with the external credential process, then waits for it to exit. If the child's exit status is non-success, Cargo reports the configured process path and the failing status. (Note: the format string carries a stray trailing backtick — a cosmetic bug.)
Solutions
- Run the credential-process binary manually with the same args/env Cargo uses to capture its stderr/exit code.
- Check the provider's own logs (most credential helpers log to stderr).
- Confirm the binary path in [registry.<name>] credential-provider is correct and executable.
- Ensure the secrets backend is unlocked and reachable from Cargo's environment.
Example fix
# before # [registry.my-registry] # credential-provider = ["cargo-cred-mgr", "get"] # provider exits 1 # after: run manually to diagnose # cargo-cred-mgr get 2>&1 | less # then fix the provider config / unlock the backend
Defensive patterns
Strategy: try-catch
Validate before calling
use std::process::Command;
fn smoke_test_credential_process(path: &str) -> Result<(), String> {
let status = Command::new(path).arg("--help").status().map_err(|e| e.to_string())?;
if status.success() { Ok(()) } else { Err(format!("{path} --help exited {status}")) }
} Try / catch
match provider.perform(®istry, &action, &args) {
Ok(resp) => { /* use resp */ }
Err(e) if e.to_string().contains("credential process")
&& e.to_string().contains("failed with status") => {
eprintln!("credential-process {} failed; run it manually to inspect stderr", path);
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Smoke-test the credential-process binary (`provider --version` / `--help`) before relying on it.
- Keep the provider's logs accessible; most write diagnostics to stderr.
- Pin the credential-process version and review it on registry/auth changes.
When it happens
Trigger: A configured credential-process performs its work (login, get, store, etc.), emits a response, but exits non-zero — e.g. the process hit an internal error after responding, or was killed.
Common situations: credential-process binary misconfigured; secret store locked or unreachable (Keychain, vault, KMS); provider crashes on a specific action; provider returns success JSON but exits 1 due to a bug.
Related errors
- multiple registries are configured with the same index url
- no credential providers could handle the request
- argument for argfile contains invalid UTF-8 characters
- argument for argfile contains newlines
- $CARGO not set
AI-assisted analysis of rust-lang/cargo@eb98b54bc9 (2026-08-11).
Data as JSON: /api/errors/d18c56a59164f1be.
Report an issue: GitHub.
Appendix: source
Thrown at src/util/credential/process.rs:80
};
let request = serde_json::to_string(&req).context("failed to serialize request")?;
tracing::debug!("credential-process < {req:?}");
writeln!(input_to_child, "{request}").context("failed to write to credential provider")?;
buffer.clear();
output_from_child
.read_line(&mut buffer)
.context("failed to read response from credential provider")?;
// Read the Credential Response
let response: Result<CredentialResponse, Error> =
serde_json::from_str(&buffer).context("failed to deserialize response")?;
tracing::debug!("credential-process > {response:?}");
// Tell the credential process we're done by closing stdin. It should exit cleanly.
drop(input_to_child);
let status = child.wait().context("credential process never started")?;
if !status.success() {
return Err(anyhow::anyhow!(
"credential process `{}` failed with status {}`",
self.path.display(),
status
)
.into());
}
tracing::trace!("credential process exited successfully");
Ok(response)
}
}
impl<'a> Credential for CredentialProcessCredential {
fn perform(
&self,
registry: &RegistryInfo<'_>,
action: &Action<'_>,
args: &[&str],
) -> Result<CredentialResponse, Error> {View on GitHub (pinned to eb98b54bc9)