microsoft/aspire · error · DistributedApplicationException
The Rust app ' ' has a Cargo --config argument that may…
Error message
The Rust app '{resourceName}' has a Cargo --config argument that may contain credentials. Generated Dockerfiles cannot embed credentials; use a hand-written Dockerfile with a BuildKit secret mount instead. What it means
Before generating a Dockerfile, the Rust generator checks the Cargo --config argument for credential-bearing content: either a sensitive config assignment (e.g. [registry] token = ...) or a URL pattern carrying credentials (user:token@host). Because the generated Dockerfile would embed the config verbatim, the library refuses to leak secrets and throws this exception.
Solutions
- Move credentials out of --config into a hand-written Dockerfile that mounts the config as a BuildKit secret (RUN --mount=type=secret,id=cargo-config).
- Use environment variables / Docker build secrets (CARGO_REGISTRIES_<NAME>_TOKEN) instead of inline config.
- Reference a checked-in, credential-free cargo config.toml file instead of an inline --config string.
- Use a pre-built image or cache mount that already has registry auth, so no credentials enter the Dockerfile.
Example fix
// before
.WithCargoArgs("--config", "registries.my-registry.token=\"ghp_secret123\"")
// after: hand-written Dockerfile
// RUN --mount=type=secret,id=cargo-config,target=/root/.cargo/config.toml cargo build --release Defensive patterns
Strategy: validation
Validate before calling
static bool ConfigMayContainCredentials(string config) =>
config.Contains("token", StringComparison.OrdinalIgnoreCase) ||
config.Contains("password", StringComparison.OrdinalIgnoreCase) ||
System.Text.RegularExpressions.Regex.IsMatch(config, @"\w+:\w+@"); // user:pass@host Try / catch
try { PublishAsync(); }
catch (DistributedApplicationException ex) when (ex.Message.Contains("may contain credentials")) {
logger.LogError("Move Cargo --config credentials to a BuildKit secret mount");
} Prevention
- Never inline registry tokens in --config arguments
- Use CARGO_REGISTRIES_*_TOKEN environment variables or BuildKit secrets
- Keep a credential-free cargo config.toml in source control
When it happens
Trigger: Calling AddRustApp(...).WithCargoArgs("--config", ...) where the config string matches SensitiveCargoConfigAssignmentPattern or CredentialBearingUrlPattern, e.g. --config 'registries.crates-io.protocol="sparse"' combined with a token, or --config containing 'https://user:token@index.crates.io'.
Common situations: Passing a private registry token inline via --config for CI; copying a cargo config that includes a credentials block; embedding net.git-fetch-with-cli credentials in args.
Related errors
- ASPIRERADIUS063
- Credential-bearing HTTP sources cannot be persisted.
- Generated Deno Dockerfiles do not support '--env-file'…
- A ConfigureRadiusInfrastructure callback changed the value…
- Aspire.Hosting.Rust requires Cargo 1.71 or later because…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/9feed80ac917508b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Rust/RustDockerfileGenerator.cs:342
private static void ValidateCargoArgumentsDoNotContainCredentials(IReadOnlyList<string> cargoArgs, string resourceName)
{
for (var i = 0; i < cargoArgs.Count; i++)
{
string? configuration = null;
if (cargoArgs[i] == "--config" && i + 1 < cargoArgs.Count)
{
configuration = cargoArgs[++i];
}
else if (cargoArgs[i].StartsWith("--config=", StringComparison.Ordinal))
{
configuration = cargoArgs[i]["--config=".Length..];
}
if (configuration is not null
&& (SensitiveCargoConfigAssignmentPattern().IsMatch(configuration)
|| CredentialBearingUrlPattern().IsMatch(configuration)))
{
throw new DistributedApplicationException(
$"The Rust app '{resourceName}' has a Cargo --config argument that may contain credentials. " +
"Generated Dockerfiles cannot embed credentials; use a hand-written Dockerfile with a BuildKit secret mount instead.");
}
}
}
// Cargo accepts configuration as either:
// --config registries.private.token="secret"
// --config=env.PGPASSWORD="secret"
// Match only credential-named assignment keys so safe settings such as
// `net.git-fetch-with-cli=true` and `registry.credential-provider=...` remain supported.
[GeneratedRegex(
"""(?:^|[.{,\s"'])(?:PGPASSWORD|MYSQL_PWD|token|password|passwd|secret|credential|api[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret|connection[_-]?strings?)(?:["']?\s*=)""",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
private static partial Regex SensitiveCargoConfigAssignmentPattern();
// A URL with user information, in the shape `scheme://userinfo@host/path`, persists
// credentials even when the configuration key itself has an ordinary name.View on GitHub (pinned to 25830f84bd)