Azure table storage returns 400 Bad Request

C#AzureExceptionAzure Table-Storage

C# Problem Overview


I ran this in debug mode, and I attach an image with the details of the exception. How can I know what went wrong? I was trying to inset data in a table. Can't azure give me more details?

Obs: The storage is on Windows Azure not on my machine. The tables were created, but I get this error when inserting data

enter image description here

// Retrieve the storage account from the connection string.
Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=***;AccountKey=***");

// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

// Create the table if it doesn't exist.
CloudTable table = tableClient.GetTableReference("EmployeeOnlineHistory");
table.CreateIfNotExists();

and here is the insert code:

public static void SetStatus(Employee e, bool value)
{
	try
	{
		// Retrieve the storage account from the connection string.
		Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=###;AccountKey=###");

		// Create the table client.
		CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

		// Create the CloudTable object that represents the "people" table.
		CloudTable table = tableClient.GetTableReference("EmployeeOnlineHistory");

		// Create a new customer entity.

		if (value == true)
		{
			EmployeeOnlineHistory empHistory = new EmployeeOnlineHistory(e.Id);
			empHistory.IsOnline = true;
			empHistory.OnlineTimestamp = DateTime.Now;
			TableOperation insertOperation = TableOperation.Insert(empHistory);
			table.Execute(insertOperation);
		}
		else
		{
			TableQuery<EmployeeOnlineHistory> query = new TableQuery<EmployeeOnlineHistory>()
				.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, e.Id.ToString()));
			EmployeeOnlineHistory entity = table.ExecuteQuery(query).Take(1).FirstOrDefault();
		   
			if ((entity!=null)&&(entity.IsOnline))
			{
				entity.IsOnline = false;
				entity.OfflineTimestamp = DateTime.Now;
				entity.OnlineTime = (entity.OfflineTimestamp - entity.OnlineTimestamp);
				TableOperation updateOperation = TableOperation.Replace(entity);
				table.Execute(updateOperation);
			}
			else
			{
				EmployeeOnlineHistory empHistory = new EmployeeOnlineHistory(e.Id);
				empHistory.IsOnline = false;
				empHistory.OfflineTimestamp = DateTime.Now;
				TableOperation insertOperation = TableOperation.Insert(empHistory);
				table.Execute(insertOperation);
			}
		}
	}
	catch (Exception ex)
	{
		//var details = new System.IO.StreamReader(((Microsoft.WindowsAzure.Storage.StorageException)ex)..Response.GetResponseStream()).ReadToEnd();
		LogFile.Error("EmployeeOnlineHistory.setStatus",ex);
	}
}

C# Solutions


Solution 1 - C#

400 Error means there's something wrong with the value of one of your properties. One way to find out is to trace the request/response through Fiddler and see the actual data being sent to Windows Azure Storage.

Taking a wild guess, I'm assuming by taking a quick glance at your code that in your model you have some Date/Time type properties (OfflineTimestamp, OnlineTimestamp) and observed that in certain scenarios one of them is initialized with the default value which is "DateTime.MinValue". Please note that the minimum value allowed for a Date/Time type attribute is Jan 1, 1601 (UTC) in Windows Azure[http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx]. Please see if that's not the case. If that's the case, then you could make them nullable type fields so that they don't get populated with the default values.

Have a look at Juha Palomäki's answer below as well... there sometimes is a slightly more useful message in the exception where he suggests (RequestInformation.ExtendedErrorInformation.ErrorMessage)

Solution 2 - C#

The StorageException contains also a little bit more detailed information about error.

Check in debugger: StorageException.RequestInformation.ExtendedInformation

enter image description here

Solution 3 - C#

In my case it was a forward slash in the RowKey.

I also received an 'OutOfRangeInput - One of the request inputs is out of range.' error when trying to add manually through the storage emulator.

> Characters Disallowed in Key Fields > > The following characters are not allowed in values for the > PartitionKey and RowKey properties: > > - The forward slash (/) character > - The backslash (\) character > - The number sign (#) character > - The question mark (?) character > - Control characters from U+0000 to U+001F, including: > - The horizontal tab (\t) character > - The linefeed (\n) character > - The carriage return (\r) character > - Control characters from U+007F to U+009F

http://msdn.microsoft.com/en-us/library/dd179338.aspx

I wrote an extension method to handle this for me.

public static string ToAzureKeyString(this string str)
{
	var sb = new StringBuilder();
	foreach (var c in str
		.Where(c => c != '/'
					&& c != '\\'
					&& c != '#'
					&& c != '/'
					&& c != '?'
					&& !char.IsControl(c)))
		sb.Append(c);
	return sb.ToString();
}

Solution 4 - C#

I faced the same issue but the reason in my case was due to size. After digging into the additional exception properties (RequestInformation.ExtendedErrorInformation), found the reason:

ErrorCode : PropertyValueTooLarge ErrorMessage: The property value exceeds the maximum allowed size (64KB). If the property value is a string, it is UTF-16 encoded and the maximum number of characters should be 32K or less.

Solution 5 - C#

well, in my case i was trying to do this:

CloudBlobContainer container = blobClient.GetContainerReference("SessionMaterials");
await container.CreateIfNotExistsAsync();

because of ContainerName SessionMaterials (as a habit writing in Pascal Case and Camel Case :D) it was causing 400 bad request. So, I just have to make it sessionmaterials. and it worked.

Hope this helps some one.

PS:- Just check exception http response or use fiddler to capture request and response.

Solution 6 - C#

Sometimes it's because your partitionKey or rowKey is NULL

(it was the case for me)

Solution 7 - C#

in my case : Container name was in capital letter. there are limitations when using chars. enter image description here

Solution 8 - C#

A documentation from MS about all the Table Service Error Codes can be found here

Solution 9 - C#

I was getting a (400) Bad Request, StatusMessage:Bad Request, ErrorCode:OutOfRangeInput when the entity had a property DateTime not set (= DateTime.MinValue)

Solution 10 - C#

I had the same BadRequest(400) Error, at the end I fill manually :

enter image description here

And worked for me. Hope this helps!

Solution 11 - C#

I also faced same kind of issue. In my case PartitionKey value was not set, so by default PartitionKey value was null, which resulted in Object reference not set to an instance of an object. exception

Check if you are providing the appropriate values for PartitionKey or RowKey, you may face such problem.

Solution 12 - C#

I fixed my cases and it worked fine

My cases:

  1. Row key is not in correct format (400).
  2. Combination of partitionkey and rowkey is not unique (409).

Solution 13 - C#

I was getting a 400 Bad Request because I was using ZRS (Zone Redundant Storage), and Analytics isn't available for this type of storage. I wasn't aware I was using Analytics.

I deleted the storage container and recreated as GRS and now it works fine.

Solution 14 - C#

In my case: I included blob metadata with a tag name containing a hyphen.

var blob = container.GetBlockBlobReference(filename);
blob.Metadata.Add("added-by", Environment.UserName);
//.. other metadata
blob.UploadFromStream(filestream);

The dash in "added-by" was the problem, and later RTFM told me that tag names must conform to C# identifier conventions.

Ref: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-properties-metadata

Underscore works fine.

Solution 15 - C#

In my case, i should not add PartitionKey and Rowkey in my entity class. It should be from the base class. Below would just work.

public class TableRunLogMessage:TableEntity
{
      public string status { get; set; }
      public long logged { get; set; }
    

      public TableRunLogMessage() { }
}

Solution 16 - C#

If you're using NodeJS and stumbled across this post, only to find that you don't get that lovely detailed information in your error object; you can utilize a proxy to get those details. However, since no one here mentions HOW to use a proxy.

The simplest way with NodeJS is by setting two environmental variables:

NODE_TLS_REJECT_UNAUTHORIZED=0
This disables SSL checks so you can intercept your own SSL requests. This leaves you open to Man-in-The-Middle attacks and should NEVER make it to production, and I wouldn't even leave it in development for long. However, it will allow you to intercept the HTTP Requests.

HTTP_PROXY=http://127.0.0.1:8888
This sets node to utilize a proxy listening on your localhost at port 8888. Port 8888 is the default for Fiddler. Many other proxies default to 8080.

If you're actually utilizing C#, like the author of this post is doing; you can simply install Fiddler and set it to intercept. By default it should intercept the requests. You may need to also trust Fiddler's certificate or otherwise do the equivalent of Node's "NODE_TLS_REJECT_UNAUTHORIZED=0".

Solution 17 - C#

I got 400-BadRequest response from Azure Storage Account Table API. Exception information showed that "The account being accessed does not support http.". I figured that we must use https in the connection string when "Secure transfer required" is enabled in storage account configuration as shown in the below image.enter image description here

Solution 18 - C#

In my case for create new instalnce of "TableBotDataStore" class (MS bot framework) we pass "tableName" parameter with hyphen like "master-bot" and TableBotDataStore can have table names only with letters and numbers only

Solution 19 - C#

I had the same issue, the function was passing the containerNameKey as string. below is the code that gave error

container = blobClient.GetContainerReference(containerNameKey) 

I changed it to

container = blobClient.GetContainerReference(ConfigurationManager.AppSettings(containerNameKey).ToString()) 

It worked

Solution 20 - C#

I got 400-BadRequest response when I tried to put too long value to the string field.

"A UTF-16-encoded value. String values may be up to 64 KiB in size. Note that the maximum number of characters supported is about 32 K or less."

https://docs.microsoft.com/en-us/rest/api/storageservices/understanding-the-table-service-data-model

Solution 21 - C#

For me I used table name with dash example: tablename: "table-1234", but tablename: "table1234" without dash worked.

Solution 22 - C#

For me, I tried to insert an entity into an Azure Storage Table with a PartitionKey/RowKey that included the "#" character. Annoying that this is disallowed, since it is common to use "#" as a separator in single-table design.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRyanView Question on Stackoverflow
Solution 1 - C#Gaurav MantriView Answer on Stackoverflow
Solution 2 - C#Juha PalomäkiView Answer on Stackoverflow
Solution 3 - C#Shawn McGoughView Answer on Stackoverflow
Solution 4 - C#Nibras MannaView Answer on Stackoverflow
Solution 5 - C#Jawand SinghView Answer on Stackoverflow
Solution 6 - C#Maroine AbdellahView Answer on Stackoverflow
Solution 7 - C#Ravi AnandView Answer on Stackoverflow
Solution 8 - C#huhaView Answer on Stackoverflow
Solution 9 - C#StigView Answer on Stackoverflow
Solution 10 - C#gatsbyView Answer on Stackoverflow
Solution 11 - C#Dilip NannawareView Answer on Stackoverflow
Solution 12 - C#KurkulaView Answer on Stackoverflow
Solution 13 - C#AidanView Answer on Stackoverflow
Solution 14 - C#Steve FriedlView Answer on Stackoverflow
Solution 15 - C#merryView Answer on Stackoverflow
Solution 16 - C#DougView Answer on Stackoverflow
Solution 17 - C#KalaiselvanView Answer on Stackoverflow
Solution 18 - C#igor_bugaenkoView Answer on Stackoverflow
Solution 19 - C#VaniView Answer on Stackoverflow
Solution 20 - C#Mika HolopainenView Answer on Stackoverflow
Solution 21 - C#EtnicView Answer on Stackoverflow
Solution 22 - C#James ShapiroView Answer on Stackoverflow