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

  1. Run the credential-process binary manually with the same args/env Cargo uses to capture its stderr/exit code.
  2. Check the provider's own logs (most credential helpers log to stderr).
  3. Confirm the binary path in [registry.<name>] credential-provider is correct and executable.
  4. 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(&registry, &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

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


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)