{"record":{"id":"b11af6345c190c33","repo":"microsoft/aspire","slug":"iam-role-arn-value-is-not-in-the-expected-form-arn-aws-iam","errorCode":null,"errorMessage":"IAM role ARN '{value}' is not in the expected form 'arn:aws:iam::<account>:role/<name>' (an optional path segment is allowed, e.g. 'arn:aws:iam::<account>:role/<path>/<name>').","messagePattern":"IAM role ARN '(.+?)' is not in the expected form 'arn:aws:iam::<account>:role/<name>' \\(an optional path segment is allowed, e\\.g\\. 'arn:aws:iam::<account>:role/<path>/<name>'\\)\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Radius/CloudProviders/CloudProviderValidation.cs","lineNumber":43,"sourceCode":"    internal static void ValidateNonEmpty(string value, string paramName)\n        => ArgumentException.ThrowIfNullOrEmpty(value, paramName);\n\n    internal static void ValidateAwsAccountId(string value, string paramName)\n    {\n        ArgumentException.ThrowIfNullOrEmpty(value, paramName);\n        if (!AwsAccountIdPattern().IsMatch(value))\n        {\n            throw new ArgumentException(\n                $\"AWS account ID '{value}' must be exactly 12 digits.\", paramName);\n        }\n    }\n\n    internal static void ValidateIamRoleArn(string value, string paramName)\n    {\n        ArgumentException.ThrowIfNullOrEmpty(value, paramName);\n        if (!IamRoleArnPattern().IsMatch(value))\n        {\n            throw new ArgumentException(\n                $\"IAM role ARN '{value}' is not in the expected form 'arn:aws:iam::<account>:role/<name>' (an optional path segment is allowed, e.g. 'arn:aws:iam::<account>:role/<path>/<name>').\",\n                paramName);\n        }\n    }\n\n    [GeneratedRegex(@\"^\\d{12}$\")]\n    private static partial Regex AwsAccountIdPattern();\n\n    // AWS IAM role ARNs may include a path between \"role/\" and the role name, e.g.\n    // arn:aws:iam::123456789012:role/division/team/RDSAccess. Each segment (path\n    // segments and the final role name) must be non-empty and may contain the\n    // characters permitted in IAM friendly names; a trailing '/' or empty segment\n    // is rejected. The character class is restricted to ASCII to avoid \\w matching\n    // non-ASCII word characters that AWS does not allow.\n    // See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-friendly-names\n    [GeneratedRegex(@\"^arn:aws:iam::\\d{12}:role/(?:[A-Za-z0-9+=,.@_-]+/)*[A-Za-z0-9+=,.@_-]+$\")]\n    private static partial Regex IamRoleArnPattern();\n}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Radius/CloudProviders/CloudProviderValidation.cs#L25-L61","documentation":"ValidateIamRoleArn rejects IAM role ARN strings that do not match the expected AWS ARN shape 'arn:aws:iam::<account>:role/<name>' (an optional path segment like 'arn:aws:iam::<account>:role/<path>/<name>' is allowed). The Aspire Radius AWS cloud provider requires a well-formed role ARN to configure the credentials the Radius runtime will use, and it fails fast rather than emitting an invalid deployment. The account id must be exactly 12 digits.","triggerScenarios":"Calling an AWS credential extension (e.g. aws.WithIrsa(...) or a role-based credential API) whose value argument is passed to CloudProviderValidation.ValidateIamRoleArn with a string that fails IamRoleArnPattern — malformed 'arn:' prefix, wrong service segment, non-12-digit account, missing '/role/' segment, or a role name containing characters outside the allowed set.","commonSituations":"Typo or truncation when pasting a role ARN from the AWS console; using an account id placeholder or short account number; confusing an IAM user ARN or instance-profile ARN with a role ARN; copying an ARN from a different partition (arn:aws-cn:, arn:aws-us-gov:) which the regex may reject; environment-variable-driven config supplying a stale value.","solutions":["Copy the full role ARN exactly from the AWS IAM console (Roles → your role → ARN) and pass it unchanged.","Verify the ARN matches arn:aws:iam:<12-digit-account-id>:role/<name> or arn:aws:iam:<12-digit-account-id>:role/<path>/<name>.","If using a non-standard partition (govcloud/china), check whether the library's regex accepts it; otherwise transform the ARN to the expected aws partition form if your account allows.","Check for whitespace, quotes, or environment-variable interpolation artifacts in the value before it reaches the API."],"exampleFix":"// before\n.WithIrsa(\"arn:aws:iam::12345:role/my-role\")\n// after\n.WithIrsa(\"arn:aws:iam::123456789012:role/my-role\")","handlingStrategy":"validation","validationCode":"// C#\nstatic bool IsValidIamRoleArn(string arn) =>\n    System.Text.RegularExpressions.Regex.IsMatch(arn ?? \"\", @\"^arn:aws:iam:\\d{12}:role(/[\\w.\\-]+)*[\\w.\\-]+$\");\n// call before passing the ARN to the credential API\nif (!IsValidIamRoleArn(roleArn)) throw new ArgumentException($\"Bad role ARN: {roleArn}\");","typeGuard":"static bool IsIamRoleArn(object? v) => v is string s && s.StartsWith(\"arn:aws:iam:\") && s.Contains(\":role/\");","tryCatchPattern":"try { builder.WithIrsa(roleArn); }\ncatch (ArgumentException ex) when (ex.ParamName == \"roleArn\") { logger.LogError(ex, \"Invalid IAM role ARN supplied\"); throw new InvalidOperationException(\"Fix the role ARN configuration\", ex); }","preventionTips":["Copy role ARNs directly from the AWS console or CLI (aws iam get-role) instead of typing them","Validate ARNs at app-model construction time with a regex before calling With* APIs","Keep ARNs in typed config sections with validation rather than raw strings","Watch for non-standard AWS partitions (govcloud/china) when the regex only accepts the aws partition"],"tags":["aws","iam","validation","radius"],"backgroundTag":"invalid-argument-format","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}