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

  1. 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).
  2. Use environment variables / Docker build secrets (CARGO_REGISTRIES_<NAME>_TOKEN) instead of inline config.
  3. Reference a checked-in, credential-free cargo config.toml file instead of an inline --config string.
  4. 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

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


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)