microsoft/aspire · error · ArgumentException

ASPIRERADIUS049

ASPIRERADIUS049

Error message

Secret-store name '{name}' is invalid. It must be 1-{RadiusSecretStoreNaming.MaxNameLength} characters of lowercase ASCII letters, digits, and '-', must start with a letter, may not contain consecutive hyphens, may not end with a hyphen, and may not be a reserved device name. Diagnostic: ASPIRERADIUS049.

What it means

AddRadiusSecretStore/WithSecretStore validates the secret-store name via ValidateStoreName because the name becomes a Kubernetes single resource-name segment. RadiusSecretStoreNaming.IsValidName requires 1-64 chars of lowercase ASCII letters, digits and '-', starting with a letter, no consecutive hyphens, no trailing hyphen, and not a reserved device name. Throwing at the API boundary avoids a failure only at cluster-apply time.

Solutions

  1. Rename the secret store to a lowercase alphanumeric string starting with a letter, using single '-' separators (e.g. 'my-store-key').
  2. If the name comes from another identifier, normalize it (lowercase, replace '_' with '-', collapse and trim hyphens) before passing it in.
  3. Check the length is within RadiusSecretStoreNaming.MaxNameLength and shorten if needed.

Example fix

// before
builder.AddRadiusSecretStore("My_SecretStore-");
// after
builder.AddRadiusSecretStore("my-secretstore");
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidStoreName(string? name) =>
    !string.IsNullOrWhiteSpace(name) && name.Length <= RadiusSecretStoreNaming.MaxNameLength &&
    RadiusSecretStoreNaming.IsValidName(name);

Try / catch

try { builder.AddRadiusSecretStore(name, ...); }
catch (ArgumentException ex) when (ex.Message.Contains("ASPIRERADIUS049")) { /* normalize name and retry */ }

Prevention

When it happens

Trigger: Calling AddRadiusSecretStore(name, ...) or WithSecretStore(name) with a null/whitespace name, an empty string, uppercase letters, underscores, a leading digit or hyphen, '--', a trailing '-', or names like 'CON'/'PRN'.

Common situations: Deriving the store name from a C# identifier or parameter name that contains underscores or uppercase; building a name by concatenation that leaves a trailing hyphen; reusing Windows device names.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/9aa63beede5ef6ad. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreExtensions.cs:387

    [Experimental("ASPIRERADIUS006", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
    private static void EnsureNotAlreadyPopulated(RadiusSecretStoreResource store)
    {
        if (store.Population.IsPopulated)
        {
            throw new InvalidOperationException(
                $"Secret store '{store.Name}' already declares a population mode; declare exactly one of " +
                "WithData, WithExistingSecret, or WithSealedSecret, once. Diagnostic: ASPIRERADIUS065.");
        }
    }

    // The store name is used verbatim as a Bicep symbol/resource name, a UCP-ID segment,
    // and a Radius-created Secret name, so it must be a valid single resource-name segment.
    private static void ValidateStoreName([NotNull] string? name)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(name);
        if (!RadiusSecretStoreNaming.IsValidName(name))
        {
            throw new ArgumentException(
                $"Secret-store name '{name}' is invalid. It must be 1-{RadiusSecretStoreNaming.MaxNameLength} characters of " +
                "lowercase ASCII letters, digits, and '-', must start with a letter, may not contain consecutive hyphens, may " +
                "not end with a hyphen, and may not be a reserved device name. Diagnostic: ASPIRERADIUS049.",
                nameof(name));
        }
    }
}

/// <summary>
/// Builds the inline <c>data</c> map for a secret store declared with <c>WithData(...)</c>.
/// </summary>
[Experimental("ASPIRERADIUS006", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
public sealed class RadiusSecretStoreDataBuilder
{
    private readonly RadiusSecretStorePopulation _population;

    internal RadiusSecretStoreDataBuilder(RadiusSecretStorePopulation population) => _population = population;

View on GitHub (pinned to 25830f84bd)