dotnet/orleans · error · ArgumentException

Key length {0} is too long to be an Azure table key. Key={1}

Error message

Key length {0} is too long to be an Azure table key. Key={1}

What it means

ArgumentException from AzureTableUtils.SanitizeTableProperty when, after replacing illegal characters, the resulting key is 1024 or more characters long. Azure Table PartitionKey/RowKey values have a 1KiB limit; the method refuses to return a key that would be rejected by the service.

Source

Thrown at src/Azure/Shared/Storage/AzureTableUtils.cs:217

        }

        /// <summary>
        /// Remove any characters that can't be used in Azure PartitionKey or RowKey values.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string SanitizeTableProperty(string key)
        {
            // Remove any characters that can't be used in Azure PartitionKey or RowKey values
            // http://www.jamestharpe.com/web-development/azure-table-service-character-combinations-disallowed-in-partitionkey-rowkey/
            key = key
                .Replace('/', '_')        // Forward slash
                .Replace('\\', '_')       // Backslash
                .Replace('#', '_')        // Pound sign
                .Replace('?', '_');       // Question mark

            if (key.Length >= 1024)
                throw new ArgumentException(string.Format("Key length {0} is too long to be an Azure table key. Key={1}", key.Length, key));

            return key;
        }

        internal static string PrintStorageException(Exception exception)
        {
            if (exception is not RequestFailedException storeExc)
            {
                throw new ArgumentException($"Unexpected exception type {exception.GetType().FullName}");
            }

            return $"Message = {storeExc.Message}, HTTP Status = {storeExc.Status}, HTTP Error Code = {storeExc.ErrorCode}.";
        }

        internal static string PointQuery(string partitionKey, string rowKey)
        {
            return TableClient.CreateQueryFilter($"(PartitionKey eq {partitionKey}) and (RowKey eq {rowKey})");
        }

View on GitHub (pinned to fca799fa70)

Solutions

  1. Hash long keys (SHA-256 hex is 64 chars) and store the full value in a separate column, using the hash as the key.
  2. Truncate or otherwise constrain the source identifier before it reaches the storage layer.
  3. Validate length before insert: if (key.Length >= 1024) use a deterministic short representation.

Example fix

// before
var rowKey = AzureTableUtils.SanitizeTableProperty(longUrl); // throws if >= 1024

// after
var rowKey = AzureTableUtils.SanitizeTableProperty(
    longUrl.Length < 1024 ? longUrl : Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(longUrl))));
Defensive patterns

Strategy: validation

Validate before calling

if (key.Length >= 1024)
    key = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(key)));
var rowKey = AzureTableUtils.SanitizeTableProperty(key);

Type guard

static bool IsKeyLengthValid(string key) => key.Length < 1024;

Prevention

When it happens

Trigger: Calling SanitizeTableProperty (or an API that uses it for PartitionKey/RowKey construction) with a string whose length >= 1024. The replacement of / \ # ? with _ does not shorten the string, so length is preserved.

Common situations: Using a long grain key (e.g. a URL or serialized object) as a PartitionKey/RowKey, hashing disabled, or a grain identity whose primary key string is unbounded. Common in grain-directory and persistence scenarios with string keys.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/fdd2f83630efbc7f. Report an issue: GitHub.