I'm using WindowsAzure.Storage nuget package version 9.0.0.
Install-Package WindowsAzure.Storage -Version 9.0.0
The following code (table.CreateIfNotExistsAsync()
) throws the error: The remote server returned an error: (409) Conflict.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference(tableName);
try
{
if (await table.CreateIfNotExistsAsync())
{
log.Info(string.Format("Created Table named: {0}", tableName));
}
}
catch (StorageException)
{
log.Error("If you are running with the default configuration please make sure you have started the storage emulator. Press the Windows key and type Azure Storage to select and run it from the list of applications - then restart the sample.");
throw;
}
return table;
If I check the StorageException details, I find this message: The table specified already exists.
Stack Trace:
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync[T](IAsyncResult result) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 57
This code works fine:
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference(tableName);
try
{
//if (await table.CreateIfNotExistsAsync())
//{
// log.Info(string.Format("Created Table named: {0}", tableName));
//}
if (!table.Exists())
{
await table.CreateAsync();
log.Info(string.Format("Created Table named: {0}", tableName));
}
}
catch (StorageException)
{
log.Error("If you are running with the default configuration please make sure you have started the storage emulator. Press the Windows key and type Azure Storage to select and run it from the list of applications - then restart the sample.");
throw;
}
return table;
I know I have tables that already exists and they are NOT currently being deleted. Why am I getting this error? Since the table does exist, I would expect this to perform and existence check and just return true, not throw a storage exception.
Edit: This is how I'm creating the CloudStorageAccount
public static CloudStorageAccount CreateStorageAccountFromConnectionString(string storageConnectionString)
{
CloudStorageAccount storageAccount;
try
{
storageAccount = CloudStorageAccount.Parse(storageConnectionString);
}
catch (FormatException fe)
{
log.Error("Invalid storage account information provided. Please confirm the AccountName and AccountKey are valid in the app.config file - then restart the application.", fe);
throw;
}
catch (ArgumentException ae)
{
log.Error("Invalid storage account information provided. Please confirm the AccountName and AccountKey are valid in the app.config file - then restart the sample.", ae);
throw;
}
return storageAccount;
}
Storage connection string looks like this:
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=something;AccountKey=somekeygoeshere==" />
CreateIfNotExists
is throwing the exception.
There was a change in implementation of the method CloudBlobContainer.CreateIfNotExists
or CloudTable.CreateIfNotExists
.
The implementation in the 7.1.2 storage client library is the following:
Make a call to check to see if the storage container or table exists (HTTP HEAD request).
If it exists do nothing.
If it doesn’t exist then make a call to create the container or table.
In the storage client library 8.1.1 the implementation is the following:
Make a call to create the container or table (HTTP PUT Request).
If an error was returned (HTTP 409) because the container or table already exists then do nothing. The error is handled.
If the container or table did not exist then create would have succeeded.
I checked with 9.0 and that behavior still exists
A nice workaround could be:
if (!container.Exists())
{
container.CreateIfNotExists();
}
How did you create CloudStorageAccount
object? I think it was probably created via SAS which doesn't have List Tables permission, so table.Exists()
always returns false per storage REST API design in order not to leak such information to unauthorized users. The reason why table.CreateIfNotExistsAsync()
didn't meet this issue is that the method directly calls Create Table REST API without a prior List Tables checking, and 409 Conflict exception is swallowed inside table.CreateIfNotExistsAsync()
method on purpose (in order to implement "create if not exists" functionality, since 409 Conflict exception means the table already exists so the method can just ignore the error and do nothing).
If my theory above applies to your case, please use a SAS with List Tables permission instead of the existing SAS, or use shared account key directly to create CloudStorageAccount
object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With