Azure / azure-storage-net

Microsoft Azure Storage Libraries for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Azure storage is requiring Cultures to be installed instead of using Invariant culture support breaking Dockerized apps etc.

JohnGalt1717 opened this issue · comments

Which service(blob, file, queue, table) does this issue concern?

Blob

Which version of the SDK was used?

Microsoft.Azure.Storage.Blob, Version=10.0.1.0 (which says that it's Culture-neutral which it isn't)

Which platform are you using? (ex: .NET Core 2.1)

.NET Core 6 RC 2

What problem was encountered?

The library requires culture info which bloats docker. It shouldn't need to use anything to do with culture ever.

How can we reproduce the problem in the simplest way?

Simply try to use the option to force .NET to use invariant culture in the csproj.

Then use the standard calls and you'll get this error on any call (because it's in authentication code)

An unhandled exception has occurred while executing the request.
Microsoft.Azure.Storage.StorageException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
en-US is an invalid culture identifier.
---> System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
en-US is an invalid culture identifier.
at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride)
at Microsoft.Azure.Storage.Core.Util.AuthenticationUtility.AppendCanonicalizedCustomHeaders(CanonicalizedString canonicalizedString, HttpRequestMessage request)
at Microsoft.Azure.Storage.Core.Auth.SharedKeyCanonicalizer.CanonicalizeHttpRequest(HttpRequestMessage request, String accountName)
at Microsoft.Azure.Storage.Auth.Protocol.StorageAuthenticationHttpHandler.GetSharedKeyAuthenticationTask(StorageRequestMessage request, CancellationToken cancellationToken)
at Microsoft.Azure.Storage.Auth.Protocol.StorageAuthenticationHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token) --- End of inner exception stack trace --- at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token

Have you found a mitigation/solution?

Not other than tripling the size of my docker image.

This isn't just a Docker issue; I think it's specific to Linux. I don't have this problem in Windows, but when I deploy on Linux I get this.

Here is the offending line:

CultureInfo sortingCulture = new CultureInfo("en-US");

For posterity, my work-around was to install the ICU library...
sudo apt install libicu-dev
... and either remove this from the csproj file (if it's there):

<ItemGroup>
	<RuntimeHostConfigurationOption Include="System.Globalization.Invariant" Value="true" />
</ItemGroup>

or add this:

<PropertyGroup>
	<InvariantGlobalization>false</InvariantGlobalization>
</PropertyGroup>

The problem with your solution @n8allan is that you increase the size of your docker container by 30% and memory usage by about the same if not more. All for the library that didn't have this dependancy before and has no justification for needing this dependency and by requiring this makes every Azure dependant project a memory and resource hog.

Correct @JohnGalt1717, it's a work-around not a solution. I highlighted what I think is the culprit above, and someone should fix it so that the library works with invariant culture, but it would need to be a member of the team that understands why "cannonized headers" are important, and whether or not en-US is actually needed for that purpose.

is this issue lost?

I am also now encountering this issue when trying to migrate to chiseled .NET 8 docker images. Specifically, using mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled in a .NET 8 app with the following line where fullSizeBlobRef is a CloudBlockBlob:

let! exists = fullSizeBlobRef.ExistsAsync() |> Async.AwaitTask

Returns the same error as in the original post:
(Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name') en-US is an invalid culture identifier.

Will have to use the jammy-chiseled-extra image instead, but seems a bit of a waste for this one issue.