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
- Hash long keys (SHA-256 hex is 64 chars) and store the full value in a separate column, using the hash as the key.
- Truncate or otherwise constrain the source identifier before it reaches the storage layer.
- 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
- Hash unbounded string keys before using them as PartitionKey/RowKey
- Store the full original value in a separate column
- Validate key length at the boundary that produces it
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
- Table name "{tableName}" is invalid according to the followi
- Unknown Playground:Storage:Provider value '{storageProvider}
- The table version entry must have a membership version.
- Value cannot be null. (Parameter 'clusterId')
- Too many rows for bulk update - max {this.StoragePolicyOptio
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/fdd2f83630efbc7f.
Report an issue: GitHub.