microsoft/aspire · error · InvalidOperationException

ASPIRERADIUS043

ASPIRERADIUS043

Error message

Secret store '{store.Name}' declares the key '{key}' more than once. Diagnostic: ASPIRERADIUS043.

What it means

ASPIRERADIUS043 duplicate-key detection in ValidateStore: population.Keys is scanned with an ordinal HashSet, and any key appearing more than once throws. This is the model-level gate that backs the duplicate rejection in the Add API; it catches duplicates declared through any path.

Solutions

  1. Remove the duplicate key declaration so each key appears once.
  2. Rename one of the conflicting keys.
  3. Deduplicate before registering (e.g. Distinct(StringComparer.Ordinal)).

Example fix

// before
store.WithExistingSecret(..., keys: ["a", "a"]);
// after
store.WithExistingSecret(..., keys: ["a"]);
Defensive patterns

Strategy: validation

Validate before calling

bool hasDuplicates = populationKeys.Distinct(StringComparer.Ordinal).Count() != populationKeys.Count();

Try / catch

try { /* validation runs */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("ASPIRERADIUS043")) { /* remove/rename the duplicated key */ }

Prevention

When it happens

Trigger: A store's population keys list contains the same key string twice (ordinal comparison), e.g. two existing/sealed key declarations with identical names, reaching validation.

Common situations: Merging two key lists that overlap; programmatic generation of keys from config that repeats; case-only differences avoided here because comparison is ordinal, so 'Key' vs 'key' are distinct but exact duplicates fail.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Radius/Secrets/RadiusSecretStoreValidation.cs:146

                "(WithData, WithExistingSecret, or WithSealedSecret); it declares " +
                $"{population.DeclaredModeCount}. Diagnostic: ASPIRERADIUS041.");
        }

        var declaredKeys = population.HasInlineData
            ? population.Data.Keys.ToList()
            : population.Keys;

        // ASPIRERADIUS043 — duplicate keys. Inline keys are rejected as they are added (the data
        // dictionary rejects a duplicate via RadiusSecretStoreDataBuilder.Add), so only the
        // existing/sealed key list needs a duplicate scan here.
        if (population.IsSecretReference)
        {
            var seen = new HashSet<string>(StringComparer.Ordinal);
            foreach (var key in population.Keys)
            {
                if (!seen.Add(key))
                {
                    throw new InvalidOperationException(
                        $"Secret store '{store.Name}' declares the key '{key}' more than once. " +
                        "Diagnostic: ASPIRERADIUS043.");
                }
            }
        }

        // ASPIRERADIUS040 — type-aware required keys.
        foreach (var required in store.Type.RequiredKeys())
        {
            if (!declaredKeys.Contains(required, StringComparer.Ordinal))
            {
                throw new InvalidOperationException(
                    $"Secret store '{store.Name}' of type '{store.Type.ToRadiusTypeString()}' is missing " +
                    $"the required key '{required}'. Diagnostic: ASPIRERADIUS040.");
            }
        }

        // ASPIRERADIUS042 / ASPIRERADIUS047 — inline bindings must be secret and use valid encoding.

View on GitHub (pinned to 25830f84bd)