System.Globalization.CultureNotFoundException: Only the invariant culture is supported
in globalization-invariant mode on mcr.microsoft.com/dotnet/runtime:10.0-alpine
comes from the image itself: it sets DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true. Install ICU and
switch the setting off, or stop asking for a named culture.
The fix that was tested adds RUN apk add --no-cache icu-libs icu-data-full
and ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false to the final stage of the
Dockerfile. The same code that crashed then printed the amount in the en-IN format.
The error
PS> docker run --rm --name fix10-dn-inv fix10-dn-alpine culture
Unhandled exception. System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
en-IN is an invalid culture identifier.
at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride)
at Program.<Main>$(String[] args) in /src/Program.cs:line 7
Why it happens
The line that throws is var ci = new CultureInfo("en-IN");. On
mcr.microsoft.com/dotnet/runtime:10.0-alpine the environment already holds
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true (it is in the output of
env inside the image, next to DOTNET_VERSION=10.0.15), so the
runtime runs in invariant mode and refused en-IN. Note the second line of
the message: "en-IN is an invalid culture identifier" is misleading, because en-IN is a
real culture; it is only unavailable in this mode.
Nothing in the project file asked for invariant mode; the base image did. The
project file is the plain console template (OutputType, TargetFramework, ImplicitUsings,
Nullable and nothing else), so the setting arrived with the
FROM line of the final stage.
To see whether an image runs in invariant mode, print its environment with the shell as the entry point. On the Alpine runtime image the first line was the setting itself:
PS> docker run --rm --name fix10-dn-icu3 --entrypoint sh fix10-dn-alpine -c env
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true
...
The fix
FROM mcr.microsoft.com/dotnet/runtime:10.0-alpine
RUN apk add --no-cache icu-libs icu-data-full
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
WORKDIR /app
COPY --from=build /out .
ENTRYPOINT ["dotnet", "ClinicApi.dll"]
PS> docker run --rm --name fix10-dn-inv2 fix10-dn-alpine-icu culture
Fee for Maria Garcia: ₹12,34,567.89
Both lines matter. Switching the variable off without the packages gives a different
crash, Couldn't find a valid ICU package installed on the system, which was
reproduced with the same image (linked below). Putting the ENV line in the
Dockerfile rather than on the docker run command keeps the setting with the
image, so every environment that runs it gets the same culture behaviour.
How it was reproduced
A console app from dotnet new console -n ClinicApi, no packages, whose
culture mode formats 1234567.89 with the C format and
new CultureInfo("en-IN"). It was published in a multi-stage Dockerfile on
mcr.microsoft.com/dotnet/sdk:10.0 (SDK 10.0.302) and run on
mcr.microsoft.com/dotnet/runtime:10.0-alpine (Alpine 3.24.4,
Microsoft.NETCore.App 10.0.15) with no extra settings, on Docker engine 29.9.3 under
Windows 11.
Frequently asked
- Why is globalization invariant mode on in my .NET Docker container?
- The mcr.microsoft.com/dotnet/runtime:10.0-alpine image sets DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true in its environment. Run env inside the image to see it. Your project file does not need to mention it.
- How do I use a culture like en-IN in a .NET Alpine container?
- Install icu-libs and icu-data-full with apk in the final stage of the Dockerfile and set ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false. After that new CultureInfo("en-IN") worked in the test.
- Is en-IN an invalid culture identifier?
- No. The message says so only because the runtime is in invariant mode, where en-IN was refused. With ICU installed and invariant mode off the same name worked.
If you switch invariant mode off and see a crash instead, read Couldn't find a valid ICU package installed on the system. More decoded errors in the Fixes category.