DevTools Hub

Search tools

Search for a developer tool

How to Parse an ARN in C#

Part of the AWS Toolkit
Pattern
string[] parts = arn.Split(':', 6);

count=6 means six pieces, not six splits — indexing past a short array throws IndexOutOfRangeException

Explanation

An ARN has six colon-separated fields, but the resource field isn't guaranteed to be colon-free — a Lambda function version ARN packs a third piece into it:

arn:aws:lambda:us-east-1:123456789012:function:my-function:1

Plain arn.Split(':') gives you eight elements here, not six, so indexing by position grabs the wrong piece. The fix is the count overload of String.Split:

string[] parts = arn.Split(':', 6);

Per the .NET docs, once the string has been split count - 1 times, "the last string in the returned array will contain this instance's remaining trailing substring, untouched." With count = 6, that's parts[5], and it absorbs every colon left over instead of stopping at the first one. Applied to the Lambda ARN above, parts[5] comes back as the full "function:my-function:1", untouched.

Note what count means here: the number of pieces you get back (6), the same convention Go's strings.SplitN and Java's String.split limit argument use — not the number of splits, which is what Python's maxsplit counts (5, for the same result). See How to Parse an ARN in Python for that version.

Indexing past the end of the returned array throws an IndexOutOfRangeException — the same sharp edge Go and Java have, and one JavaScript's array indexing and Python's destructuring assignment don't. A truncated or malformed ARN can legitimately produce fewer than six elements; reading parts[5] without checking parts.Length first crashes instead of producing a wrong-but-safe result.

The same colons-in-the-resource trap applies to a hand-written regex, too: a pattern using [^:]+ for every group excludes colons entirely, so it won't match the Lambda ARN at all — use a greedy (.+) for the final group instead.

For the full field-by-field breakdown of a specific ARN, see ARN Parser. For what each field means, see What Is an ARN?

Valid examples

  • "arn:aws:iam::123456789012:user/john".Split(':', 6) → [arn, aws, iam, , 123456789012, user/john]

    Exactly six pieces — the count doesn't change anything when there's nothing extra to protect.

  • "arn:aws:lambda:us-east-1:123456789012:function:my-function:1".Split(':', 6) → [..., function:my-function:1]

    The sixth element absorbs both remaining colons instead of being cut off at the first one.

  • "arn:aws:s3:::amzn-s3-demo-bucket/Development/*".Split(':', 6) → [arn, aws, s3, , , amzn-s3-demo-bucket/Development/*]

    region and account ID both come back as empty strings for an S3 bucket ARN — present, just empty.

Invalid examples

  • arn.Split(':')[5] // "function", not "function:my-function:1"

    Splitting with no count and indexing by position — the Lambda ARN above has 8 parts, not 6, so [5] grabs the wrong piece.

  • "arn:aws:s3".Split(':', 6)[5]

    A truncated ARN produces only 3 elements — indexing [5] without checking parts.Length first throws IndexOutOfRangeException.

  • new Regex(@"^arn:([^:]+):([^:]+):([^:]*):([^:]*):([^:]+)$")

    Every group uses [^:]+ — fails to match the Lambda ARN, since its resource part contains colons the pattern explicitly excludes.

Try it now