rust-lang/cargo · error · anyhow::Error

credential process `{}` failed with status {}`

Error message

credential process `{}` failed with status {}`

What it means

CredentialProcessCredential::run spawns an external process implementing cargo's credential protocol, exchanges hello/request/response JSON over stdin/stdout, then waits for the child. If the child exits with a non-zero status, Cargo reports the configured credential-process path and the exit status. The failure originates inside the external provider, not in cargo's protocol handling.

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 0e07a15537)

Solutions

  1. Run the credential-process binary manually with `--cargo-plugin` and a JSON request to see its native error output.
  2. Check the binary's own logs / stderr for the underlying failure.
  3. Verify the binary path in config.toml is correct and executable.
  4. Update or reinstall the credential-process tool; fall back to `cargo:token` while debugging.

Example fix

// config.toml before
[registry]
global-credential-providers = ["cred-proc"]
credential-process = "/wrong/path/cred-proc"

// after (correct path + working binary)
[registry]
global-credential-providers = ["cred-proc"]
credential-process = "/usr/local/bin/cred-proc"
Defensive patterns

Strategy: try-catch

Validate before calling

use std::path::Path;
fn credential_process_runnable(path: &str) -> bool {
    Path::new(path).is_file()
        && std::process::Command::new(path).arg("--version").output().is_ok()
}

Try / catch

match provider.perform(&registry, &action, &args[1..]) {
    Err(e) => {
        let msg = e.to_string();
        if msg.contains("credential process") && msg.contains("failed with status") {
            eprintln!("external credential process exited non-zero; check its logs / path");
        }
        return Err(e);
    }
    r => r,
}

Prevention

When it happens

Trigger: A configured `credential-process` binary (set in config.toml) crashes, panics, is killed, or returns a non-zero exit code after (or before) completing the protocol exchange for a get/store/erase/forget action.

Common situations: The credential-process binary has a bug, is missing a dependency, cannot reach its backend (1Password, Vault, keychain daemon), the binary path is wrong so the OS returns an error code, or the process was OOM-killed/SIGKILLed.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/d18c56a59164f1be.json. Report an issue: GitHub.