{"record":{"id":"fdd2f83630efbc7f","repo":"dotnet/orleans","slug":"key-length-0-is-too-long-to-be-an-azure-table-ke","errorCode":null,"errorMessage":"Key length {0} is too long to be an Azure table key. Key={1}","messagePattern":"Key length (.+?) is too long to be an Azure table key\\. Key=(.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Azure/Shared/Storage/AzureTableUtils.cs","lineNumber":217,"sourceCode":"        }\n\n        /// <summary>\n        /// Remove any characters that can't be used in Azure PartitionKey or RowKey values.\n        /// </summary>\n        /// <param name=\"key\"></param>\n        /// <returns></returns>\n        public static string SanitizeTableProperty(string key)\n        {\n            // Remove any characters that can't be used in Azure PartitionKey or RowKey values\n            // http://www.jamestharpe.com/web-development/azure-table-service-character-combinations-disallowed-in-partitionkey-rowkey/\n            key = key\n                .Replace('/', '_')        // Forward slash\n                .Replace('\\\\', '_')       // Backslash\n                .Replace('#', '_')        // Pound sign\n                .Replace('?', '_');       // Question mark\n\n            if (key.Length >= 1024)\n                throw new ArgumentException(string.Format(\"Key length {0} is too long to be an Azure table key. Key={1}\", key.Length, key));\n\n            return key;\n        }\n\n        internal static string PrintStorageException(Exception exception)\n        {\n            if (exception is not RequestFailedException storeExc)\n            {\n                throw new ArgumentException($\"Unexpected exception type {exception.GetType().FullName}\");\n            }\n\n            return $\"Message = {storeExc.Message}, HTTP Status = {storeExc.Status}, HTTP Error Code = {storeExc.ErrorCode}.\";\n        }\n\n        internal static string PointQuery(string partitionKey, string rowKey)\n        {\n            return TableClient.CreateQueryFilter($\"(PartitionKey eq {partitionKey}) and (RowKey eq {rowKey})\");\n        }","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Shared/Storage/AzureTableUtils.cs#L199-L235","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar rowKey = AzureTableUtils.SanitizeTableProperty(longUrl); // throws if >= 1024\n\n// after\nvar rowKey = AzureTableUtils.SanitizeTableProperty(\n    longUrl.Length < 1024 ? longUrl : Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(longUrl))));","handlingStrategy":"validation","validationCode":"if (key.Length >= 1024)\n    key = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(key)));\nvar rowKey = AzureTableUtils.SanitizeTableProperty(key);","typeGuard":"static bool IsKeyLengthValid(string key) => key.Length < 1024;","tryCatchPattern":null,"preventionTips":["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"],"tags":["argument-validation","azure-storage","data-model","naming"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}