microsoft/aspire · error · InvalidOperationException
Unknown AWS credential type
Error message
Unknown AWS credential type '{credential.GetType().Name}'. What it means
While computing a stable identity for an AWS Radius credential (AccessKey or Irsa are the known shapes), any other AwsRadiusCredential subtype has no identity rule, so validation throws this InvalidOperationException as an exhaustiveness guard.
Solutions
- Use only supported AWS credential kinds: AwsRadiusCredential.AccessKey or AwsRadiusCredential.Irsa.
- Align package versions so the credential type comes from the same Aspire.Hosting.Radius version as the validator.
- Report the unrecognized type name (from the message) to the Aspire maintainers if it is a shipped type.
Example fix
// before var credential = new MyCustomAwsRadiusCredential(accessKey, secretKey); env.WithRadiusCredential(credential); // after var credential = new AwsRadiusCredential.AccessKey(accessKeyIdParameter, secretAccessKeyParameter); env.WithRadiusCredential(credential);
Defensive patterns
Strategy: type-guard
Validate before calling
// Validate the credential kind before registering
bool IsSupportedAwsCredential(AwsRadiusCredential c) =>
c is AwsRadiusCredential.AccessKey or AwsRadiusCredential.Irsa;
if (!IsSupportedAwsCredential(credential)) throw new ArgumentException($"Unsupported AWS credential type {credential.GetType().Name}"); Type guard
var ok = credential is AwsRadiusCredential.AccessKey or AwsRadiusCredential.Irsa;
Try / catch
try { env.WithRadiusCredential(credential); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Unknown AWS credential type"))
{
logger.LogError(ex, "Credential type {Type} is not supported; use AccessKey or Irsa.", credential.GetType().Name);
} Prevention
- Only construct AwsRadiusCredential.AccessKey or AwsRadiusCredential.Irsa
- Do not subclass AwsRadiusCredential
- Align Aspire.Hosting.Radius package versions across projects
When it happens
Trigger: Supplying a custom or version-mismatched subclass of AwsRadiusCredential to a Radius environment credential registration, then running the credential-conflict validation (ValidateNoConflictingInstallationCredentials).
Common situations: Mixed Aspire.Hosting.Radius package versions across a solution; a hand-written subclass of AwsRadiusCredential; refactoring that accidentally casts the wrong credential object into the AWS slot.
Related errors
- Unknown Azure credential type
- ASPIRERADIUS011
- AWS account ID ' ' must be exactly 12 digits.
- IAM role ARN ' ' is not in the expected form 'arn:aws:iam:…
- A ConfigureRadiusInfrastructure callback changed the value…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/8334a1356d14d582.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Radius/Publishing/RadCredentialRegisterStep.cs:234
$"are shared across all environments, but environments {envNames} configure different {provider} " +
"credentials that would overwrite one another. Configure a single shared credential for all " +
"environments, or deploy them to separate Radius installations. Diagnostic: ASPIRERADIUS011.");
}
private static string AzureCredentialIdentity(AzureRadiusCredential credential) => credential switch
{
AzureRadiusCredential.ServicePrincipal sp => $"sp|{Canonicalize(sp.TenantId)}|{Canonicalize(sp.ClientId)}",
AzureRadiusCredential.WorkloadIdentity wi => $"wi|{Canonicalize(wi.TenantId)}|{Canonicalize(wi.ClientId)}",
_ => throw new InvalidOperationException($"Unknown Azure credential type '{credential.GetType().Name}'."),
};
private static string AwsCredentialIdentity(AwsRadiusCredential credential) => credential switch
{
// The access key id identifies the principal; it is bound via a parameter, so its
// resource name is used as a stable proxy without resolving the value here.
AwsRadiusCredential.AccessKey ak => $"access-key|{ak.AccessKeyId.Resource.Name}",
AwsRadiusCredential.Irsa irsa => $"irsa|{irsa.IamRoleArn}",
_ => throw new InvalidOperationException($"Unknown AWS credential type '{credential.GetType().Name}'."),
};
// Inputs are validated as GUIDs before reaching here; normalize to the canonical "D"
// form so differing casing/formatting of the same GUID is not treated as a conflict.
private static string Canonicalize(string guid)
=> Guid.TryParse(guid, out var parsed) ? parsed.ToString("D") : guid;
private static async Task<string> ResolveParameterAsync(
IResourceBuilder<ParameterResource> parameter,
CancellationToken cancellationToken)
{
return await parameter.Resource.GetValueAsync(cancellationToken).ConfigureAwait(false) ?? string.Empty;
}
private static async Task RunRadAsync(
IReadOnlyList<string> args,
HashSet<string> secretFlags,
ILogger logger,View on GitHub (pinned to 25830f84bd)