'Running .NET 6 project in Docker throws Globalization.CultureNotFoundException

I have upgraded API project from .NET 5 to .NET 6 successfully and running fine when executed locally (without Docker).

I have also updated the version in Dockerfile from "5.0-alpine3.13" to "6.0-alpine3.14" as below (only change I made).

ARG VERSION=6.0-alpine3.14

#Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base
EXPOSE 8080
ENV DOTNET_RUNNING_IN_CONTAINER=true \
  ASPNETCORE_URLS=http://+:8080

#Build stage
FROM mcr.microsoft.com/dotnet/sdk:$VERSION AS build
WORKDIR /src
COPY ["/src/RM.Api/RM.Api.csproj", "/src/RM.Api/"]
RUN dotnet restore "/src/RM.Api/RM.Api.csproj"
COPY . .
WORKDIR "/src/src/RM.Api"

#Publish dotnet project
FROM build AS publish
ARG BUILDCONFIG=RELEASE
RUN dotnet publish "RM.Api.csproj" -c $BUILDCONFIG -o /app/publish

#Create local user, change ownership, and copy artifacts
FROM base AS final
WORKDIR /app
RUN adduser \
  --disabled-password \
  --home /app \
  --gecos '' app \
  && chown -R app /app
USER app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RM.Api.dll"]

But when I run this .NET 6 project in Docker it throws the below Azure.Storage exception in the Startup.cs file.

API-Startup.cs

Full stack trace is here.

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.<>n__0(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>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](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
--- End of inner exception stack trace ---
at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
at Microsoft.Azure.Storage.Blob.CloudBlobContainer.CreateAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
at Microsoft.Azure.Storage.Blob.CloudBlobContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType accessType, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
at RM.Api.Startup.ConfigureServices(IServiceCollection services) in /src/src/RM.Api/Startup.cs:line 91

I have updated the Dockerfile as below but it did not work. Can any one help here?

ARG VERSION=6.0-alpine3.14

#Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base
EXPOSE 8080
ENV DOTNET_RUNNING_IN_CONTAINER=true \
  ASPNETCORE_URLS=http://+:8080

#Build stage
FROM mcr.microsoft.com/dotnet/sdk:$VERSION AS build
WORKDIR /src
COPY ["/src/RM.Api/RM.Api.csproj", "/src/RM.Api/"]
RUN dotnet restore "/src/RM.Api/RM.Api.csproj"
COPY . .
WORKDIR "/src/src/RM.Api"

RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib

ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true

#Publish dotnet project
FROM build AS publish
ARG BUILDCONFIG=RELEASE
RUN dotnet publish "RM.Api.csproj" -c $BUILDCONFIG -o /app/publish

#Create local user, change ownership, and copy artifacts
FROM base AS final
WORKDIR /app
RUN adduser \
  --disabled-password \
  --home /app \
  --gecos '' app \
  && chown -R app /app
USER app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RM.Api.dll"]

========UPDATE==========

Making the following two changes resolved the issue.

  1. Updating the Dockerfile as below

    ARG VERSION=6.0-alpine3.14

    #Runtime stage FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base EXPOSE 8080 ENV DOTNET_RUNNING_IN_CONTAINER=true
    ASPNETCORE_URLS=http://+:8080 RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false

  2. Added the below in .csproj file

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


Solution 1:[1]

You've put the ENV statement in the 'build' part of the Dockerfile which means that it doesn't get placed in the final image. Either put it in the 'base' part or the 'final' part.

I'd put it in the 'base' section with the other ENV statements.

You might also want to move the apk add to the base or final sections of the file, if you want the software installed in the final image.

Solution 2:[2]

Making the following two changes resolved the issue.

  1. Updating the Dockerfile as below

    ARG VERSION=6.0-alpine3.14

    #Runtime stage FROM mcr.microsoft.com/dotnet/aspnet:$VERSION AS base EXPOSE 8080

    ENV DOTNET_RUNNING_IN_CONTAINER=true
    ASPNETCORE_URLS=http://+:8080

    RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib

    ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false

  2. Added the below in .csproj file

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

Solution 3:[3]

Your docker file should look like this for the base section:

FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base
WORKDIR /app
RUN apk add --no-cache icu-libs
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
EXPOSE 80
EXPOSE 443

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Bhanu
Solution 3 Emir K?l?nç