I am making use of a Redis database for Data Protection on .net core 3.0 on Kubernetes, but still get the below error. Any ideas?
fail: Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery[7]
An exception was thrown while deserializing the token. Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The
antiforgery token could not be decrypted. --->
System.Security.Cryptography.CryptographicException: The key
{ffb146a1-0e5e-4f96-8566-425f7c2eb99a} was not found in the key ring.
at
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[]
protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus&
status) at
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[]
protectedData, Boolean ignoreRevocationErrors, Boolean&
requiresMigration, Boolean& wasRevoked) at
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[]
protectedData) at
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String
serializedToken) --- End of inner exception stack trace --- at
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String
serializedToken) at
Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext
httpContext)
var redis = ConnectionMultiplexer.Connect(Environment.GetEnvironmentVariable("REDIS_CONNSTR"));
services.AddDataProtection().PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
According to the documentation in the below article the application name needs to be set.
services.AddDataProtection()
.PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys")
.SetApplicationName("product");
By default, the Data Protection system isolates apps from one another
based on their content root paths, even if they're sharing the same
physical key repository. This prevents the apps from understanding
each other's protected payloads.
To share protected payloads among apps:
Configure SetApplicationName in each app with the same value.
https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.0
Just a further note on this. If you get a 400 Bad Request and are using an API in the same solution then I would suggest having a look at the IgnoreAntiforgeryToken Attribute to decorate methods where CSRF does not apply.
[HttpPost]
[IgnoreAntiforgeryToken]
Related
I'm trying to add multiple Microsoft Authentication Providers to my ASP.NET Core Application and dynamically show one of them on the login site based on the url parameter (tenant).
I have this loop:
var authBuilder = services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
foreach (var microsoftExternalProvider in securityOptions.ExternalAuthentication.Microsoft)
{
authBuilder.AddMicrosoftAccount(microsoftExternalProvider.Name, microsoftOptions => {
microsoftOptions.ClientId = microsoftExternalProvider.ClientId;
microsoftOptions.ClientSecret = microsoftExternalProvider.ClientSecret;
if (microsoftExternalProvider.IsSingleTenant)
{
microsoftOptions.AuthorizationEndpoint = $"https://login.microsoftonline.com/{microsoftExternalProvider.TenantId}/oauth2/v2.0/authorize";
microsoftOptions.TokenEndpoint = $"https://login.microsoftonline.com/{microsoftExternalProvider.TenantId}/oauth2/v2.0/token";
}
});
}
I'm taking ids and secrets from array in appsettings.json.
The problem is that only the first provider set up in appsettings works. The other ones after trying to log in throw an exception:
System.Exception: An error was encountered while handling the remote login.
---> System.Exception: The oauth state was missing or invalid.
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
What should I do to make all the providers work? Couldn't find any information about adding "AddMicrosoftAccount()" more then once. That's really important for me to be able to log in from different tenants in different organizations. It can't be just one multi-tenant provider - business requirement.
The problem is that each provider has the same default callback path - "/signin-microsoft".
The solution is to configure it in the loop like this for example:
microsoftOptions.CallbackPath = new PathString($"/signin-microsoft-{microsoftExternalProvider.Name}");
and set azure active directory app authentication web redirect url to proper url.
We have a .Net Core 3.1 web app that uses Microsoft.AspNetCore.DataProtection version 3.1.0 to encrypt and decrypt data. The application all of the sudden fails to decrypt the data because of the error "The payload was invalid" as seen below:
[2021-08-18 08:12:19 ERR] [FoxCentral.Web.Api.ErrorController] Path: /api/botflows/2. Error: The payload was invalid.
Trace: at Microsoft.AspNetCore.DataProtection.Cng.CbcAuthenticatedEncryptor.DecryptImpl(Byte* pbCiphertext, UInt32 cbCiphertext, Byte* pbAdditionalAuthenticatedData, UInt32 cbAdditionalAuthenticatedData)
at Microsoft.AspNetCore.DataProtection.Cng.Internal.CngAuthenticatedEncryptorBase.Decrypt(ArraySegment`1 ciphertext, ArraySegment`1 additionalAuthenticatedData)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
We store the keys in a database using Entity Framework Core and use X509 certificates to protect the keys. Below is how we set up data protection in our app:
var protectionBuilder = services.AddDataProtection();
protectionBuilder.PersistKeysToDbContext<KeysContext>();
protectionBuilder.ProtectKeysWithCertificate(certificates.KeyProtectCertificate)
.UnprotectKeysWithAnyCertificate(certificates.KeyUnprotectCertificates.ToArray());
All the data was encrypted and decrypted on the same server. What causes that decryption failure? How to recover the data?
I found keys have a 90-day lifetime by default that why you cause the problem.
And I suggest you use IKeyManager to generate a new key, it maybe can help you recover data.
Offical doc:
Automatic key ring refresh
using Microsoft.AspNetCore.DataProtection;
services.AddDataProtection()
.SetApplicationName("ProjectName")
.AddKeyManagementOptions(options =>
{
options.NewKeyLifetime = new TimeSpan(180, 0, 0, 0);
options.AutoGenerateKeys = true;
});
I get these these two exceptions in Identity Server 4 during a regular login to get a token.
It's on a load balanced setup with 2 servers, so I've done the following:
They both get the same PFX for encrypting tokens. It works just fine on a single server. They have the password for the PFX file, and can seemingly encrypt a token correct correctly.
Sometimes the flow works well, but it always fails on giving CORS access on the connect/token endpoint. I can see that the CORS Middleware plays a role here, but I don't understand why the signing are credentials during the verification of CORS access. I've added protection here, and during startup, I verify that the private key for both the protectionCert and the signing credentials exist. Both certs are password-protected files included with the deploy just to keep it simple(i.e. not running into access issues on private key).
Why is it all of a sudden having trouble getting access to the private key during the CORS operation though? That part I do not understand. All of this works on my test environment, which runs on a single machine, so I'm 99% sure it has to do with this setup being load balanced. Also wondering, if I can save myself a headache by enabling sticky sessions in the load balancer.
In my DataProtection store there's only a single key saved. Not sure if that's normal. I would expect the application to generate more keys.
services.AddDataProtection()
.SetApplicationName("MyApp")
.PersistKeysToDbContext<DataProtectionKeyContext>()
.ProtectKeysWithCertificate(protectionCert);
var cert = new X509Certificate2("signing.pfx",
configuration.GetValue<string>("AppSettings:SigningCredentials:FilePassword"));
builder.AddSigningCredential(cert);
Unhandled exception: "Keyset does not exist" ";"Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
at System.Security.Cryptography.CngKey.Open(String keyName, CngProvider provider, CngKeyOpenOptions openOptions)
at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKeyStatus()
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt)
at IdentityServer4.Services.DefaultTokenCreationService.CreateTokenAsync(Token token)
at IdentityServer4.Services.DefaultTokenService.CreateSecurityTokenAsync(Token token)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.CreateAccessTokenAsync(ValidatedTokenRequest request)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAuthorizationCodeRequestAsync(TokenRequestValidationResult request)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAsync(TokenRequestValidationResult request)
at IdentityServer4.Endpoints.TokenEndpoint.ProcessTokenRequestAsync(HttpContext context)
at IdentityServer4.Endpoints.TokenEndpoint.ProcessAsync(HttpContext context)
at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
Connection ID ""17365880169046365174"", Request ID ""800253f9-0001-f100-b63f-84710c7967bb"": An unhandled exception was thrown by the application.";
"Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
at System.Security.Cryptography.CngKey.Open(String keyName, CngProvider provider, CngKeyOpenOptions openOptions)
at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKey()
at Microsoft.IdentityModel.Tokens.X509SecurityKey.get_PrivateKeyStatus()
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider..ctor(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateSignatureProvider(SecurityKey key, String algorithm, Boolean willCreateSignatures)
at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(String input, SigningCredentials signingCredentials)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)
at IdentityServer4.Services.DefaultTokenCreationService.CreateJwtAsync(JwtSecurityToken jwt)
at IdentityServer4.Services.DefaultTokenCreationService.CreateTokenAsync(Token token)
at IdentityServer4.Services.DefaultTokenService.CreateSecurityTokenAsync(Token token)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.CreateAccessTokenAsync(ValidatedTokenRequest request)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAuthorizationCodeRequestAsync(TokenRequestValidationResult request)
at IdentityServer4.ResponseHandling.TokenResponseGenerator.ProcessAsync(TokenRequestValidationResult request)
at IdentityServer4.Endpoints.TokenEndpoint.ProcessTokenRequestAsync(HttpContext context)
at IdentityServer4.Endpoints.TokenEndpoint.ProcessAsync(HttpContext context)
at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events)
at IdentityServer4.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>g__InvokeCoreAwaited|15_0(HttpContext context, Task`1 policyTask)
at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at NewRelic.Providers.Wrapper.AspNetCore.WrapPipelineMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
I think I solved it. I read that it could have to do with lack of access. I guess on of my tasks in my CD setup isn't working right, because I tried running an APP CMD command to set user profile to loaded as true for my app pool. Supposedly, if this flag is false, the application will by default try to store the private key as the current user, but since no user is loaded, this doesn't work. So I tried with ephemeral keyset instead(in-memory) to avoid access issues and now it works. Not sure what the consequences are of using an in-memory keyset, if the keys are appropriate etc.
I have an API with a single endpoint that retrieves documents from a CosmosDB collection. The endpoint works fine on common scenarios. However, when I execute stress tests on the API, to measure how it responds under heavy load, I experience outages on the site (site starts to respond requests with 502 - bad gateway).
Searching on Application Insights, I notice OutOfMemory exceptions raising while executing the sentence to retrieve the documents from the CosmosDB collection. The method that I'm using to read the documents is ReadNextAsync and the logs points this line specifically.
We read and tested the best practices and tips that the Cosmos DB documentation mentions to discard a bad usage of the SDK from our side, but even trying with different configurations (MaxItemCount, MaxBufferedItems, MaxConcurrency), the issue persisted.
After executing several tests, I noticed that if I limit the amount of documents to retrieve from the collection (e.g. using a TOP 40 clause), the exceptions or site outages don’t show. Instead, all requests are processed successfully with 200 status code. As I haven’t had these kind of issues on our Full FWK API, which has the exactly same logic as the .NET Core API described here, I'm wondering whether I could be doing a bad usage of the .NET Core SDK.
In order to share more context, I detailed below the general specifications and also the details on how I configured CosmosDB, along with the implementation to retrieve documents. Additionally, I included logs and a related stack trace found on Application Insights exceptions table.
General Specifications
API .NET CORE 2.2
Microsoft.Azure.Cosmos 3.5.0
Cosmos DB specifications
CosmosDB client connection
Connection mode: Direct
Application Region: West US
Default values for the rest
CosmosDB target collection
~600 documents
~30K size each document
PartitionKey -> id (one logical partition per document)
Write region -> West US
Read regions -> West Us, West Europe, Southeast Asia and Brazil South
Stress scenario details
Execute 400 request per second looking for retrieving up to 200 documents per request.
Document retrieving implementation
var feed = container.GetItemLinqQueryable<T>(false, null, queryRequestOptions).Where(predicate).ToFeedIterator();
var batches = new List<FeedResponse<T>>();
while (feed.HasMoreResults)
{
var batch = await feed.ReadNextAsync();
batches.Add(batch);
}
Application Insights exception stack trace
Response status code does not indicate success: 500 Substatus: 0 Reason: (System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Collections.Generic.List`1.set_Capacity(Int32 value)
at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
at System.Collections.Generic.List`1.AddWithResize(T item)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParsePropertyNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseArrayNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParsePropertyNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseObjectNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.ParseNode(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator.Parser.Parse(IJsonReader jsonTextReader)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.JsonTextNavigator..ctor(ReadOnlyMemory`1 buffer, Boolean skipValidation)
at Microsoft.Azure.Cosmos.Json.JsonNavigator.Create(ReadOnlyMemory`1 buffer, JsonStringDictionary jsonStringDictionary, Boolean skipValidation)
at Microsoft.Azure.Cosmos.CosmosElements.CosmosElementSerializer.ToCosmosElements(MemoryStream memoryStream, ResourceType resourceType, CosmosSerializationFormatOptions cosmosSerializationOptions)
at Microsoft.Azure.Cosmos.CosmosQueryClientCore.GetCosmosElementResponse(QueryRequestOptions requestOptions, ResourceType resourceType, ResponseMessage cosmosResponseMessage, PartitionKeyRangeIdentity partitionKeyRangeIdentity, SchedulingStopwatch schedulingStopwatch)
at Microsoft.Azure.Cosmos.CosmosQueryClientCore.ExecuteItemQueryAsync[RequestOptionType](Uri resourceUri, ResourceType resourceType, OperationType operationType, RequestOptionType requestOptions, SqlQuerySpec sqlQuerySpec, String continuationToken, PartitionKeyRangeIdentity partitionKeyRange, Boolean isContinuationExpected, Int32 pageSize, SchedulingStopwatch schedulingStopwatch, CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.ItemProducer.BufferMoreDocumentsAsync(CancellationToken token)
at Microsoft.Azure.Cosmos.Query.ItemProducer.BufferMoreIfEmptyAsync(CancellationToken token)
at Microsoft.Azure.Cosmos.Query.ItemProducer.TryMoveNextPageAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.ItemProducerTree.TryMoveNextPageImplementationAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.ItemProducerTree.ExecuteWithSplitProofingAsync(Func`2 function, Boolean functionNeedsBeReexecuted, CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.ItemProducerTree.TryMoveNextPageAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.CosmosParallelItemQueryExecutionContext.DrainAsync(Int32 maxElements, CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.PipelinedDocumentQueryExecutionContext.ExecuteNextAsync(CancellationToken token)
at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.LazyCosmosQueryExecutionContext.ExecuteNextAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.CosmosQueryExecutionContextWithNameCacheStaleRetry.ExecuteNextAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Cosmos.Query.Core.ExecutionContext.CatchAllCosmosQueryExecutionContext.ExecuteNextAsync(CancellationToken cancellationToken)).
{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.ResponseMessage.EnsureSuccessStatusCode","level":0,"line":0}
{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.CosmosResponseFactory.CreateQueryFeedResponseHelper","level":1,"line":0}
{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.CosmosResponseFactory.CreateQueryFeedResponse","level":2,"line":0}
{"assembly":"Microsoft.Azure.Cosmos.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","method":"Microsoft.Azure.Cosmos.FeedIteratorCore`1+<ReadNextAsync>d__5.MoveNext","level":3,"line":0}
I've not used cosmosdb so not sure if this really relevant but accroding to the azure documentation each request is limited 4MB per request.
Am I correct in thinking in the example code you have given above there is no filtering? Meaning all 600 documents (~30k each) are returned?
You might have more success trying to split this into multipl requests
I keep getting the following exception when trying to upload a file to Amazon Glacier using the .NET sdk:
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Amazon.Glacier.Model.Internal.MarshallTransformations.UploadArchiveResponseUnmarshaller.UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)
at Amazon.Runtime.Internal.Transform.JsonResponseUnmarshaller.UnmarshallException(UnmarshallerContext input, Exception innerException, HttpStatusCode statusCode)
at Amazon.Runtime.AmazonWebServiceClient.handleHttpWebErrorResponse(AsyncResult asyncResult, WebException we)
at Amazon.Runtime.AmazonWebServiceClient.getResponseCallback(IAsyncResult result)
at Amazon.Runtime.AmazonWebServiceClient.endOperation[T](IAsyncResult result)
at Amazon.Glacier.Transfer.Internal.SinglepartUploadCommand.Execute()
at Amazon.Glacier.Transfer.ArchiveTransferManager.Upload(String vaultName, String archiveDescription, String filepath, UploadOptions options)
at UClaim.TaskRunner.Tasks.ArchiveDocuments.Execute() in c:\Projects\uclaim\src\UClaim.TaskRunner\Tasks\ArchiveDocuments.cs:line 55
I've got no idea why it's happening or what it means, and googling is turning up nothing. The code I'm using is nothing special, but here it is for completeness.
var document = GetDocumentToArchive();
var manager = new ArchiveTransferManager(Amazon.RegionEndpoint.EUWest1);
document.ArchiveId = manager.Upload(
"archivedDocs",
string.Format("#{0}: {1}", document.Claim.Id, document.Description),
document.GeneratePathOnServer()).ArchiveId;
Ok turns out this was a stupid mistake. I thought that the SDK would create the vault if it didn't exist but I guess it was attempting to look it up and failing. I logged in to the management console and created the "archivedDocs" vault and now it runs fine