System.DllNotFoundException: Unable to load shared library 'libSkiaSharp' or one of its dependencies. ... in a Linux container means the app has the SkiaSharp package but not a Linux build of its native library. Add SkiaSharp.NativeAssets.Linux.NoDependencies at the same version as SkiaSharp.

In the test, one dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies --version 3.119.0 in the Dockerfile made the same code run on runtime:10.0.

The error

PS> docker run --rm --name fix10-dn-s1 fix10-dn-lab skia
Unhandled exception. System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception.
 ---> System.DllNotFoundException: Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable:
/usr/share/dotnet/shared/Microsoft.NETCore.App/10.0.13/libSkiaSharp.so: cannot open shared object file: No such file or directory
/app/libSkiaSharp.so: cannot open shared object file: No such file or directory
...
   at SkiaSharp.SKBitmap..ctor(Int32 width, Int32 height, Boolean isOpaque)
   at Program.<Main>$(String[] args) in /src/Program.cs:line 27

Why it happens

The project referenced only SkiaSharp 3.119.0. The managed DLL was there, but when new SKBitmap(10, 10) first called into native code, the runtime looked for libSkiaSharp.so in the runtime folder and in /app and found it in neither. The error came at run time; the image had built without complaint.

The Alpine image gave the same top line with a different list of attempts, each ending in Error loading shared library ... No such file or directory:

PS> docker run --rm --name fix10-dn-s3 fix10-dn-lab-alpine skia
Unhandled exception. System.TypeInitializationException: The type initializer for 'SkiaSharp.SKImageInfo' threw an exception.
 ---> System.DllNotFoundException: Unable to load shared library 'libSkiaSharp' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable:
Error loading shared library /usr/share/dotnet/shared/Microsoft.NETCore.App/10.0.15/libSkiaSharp.so: No such file or directory
...

The list under the message is a record of where the runtime looked. On runtime:10.0 it named eight paths: the shared runtime folder and /app, each with and without a lib prefix and a .so suffix. On Alpine there were twelve, adding the bare names. In both cases /app/libSkiaSharp.so was one of the paths, so that is the file the publish output was missing.

The fix

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY ClinicApi.csproj .
RUN dotnet add package SkiaSharp.NativeAssets.Linux.NoDependencies --version 3.119.0
RUN dotnet restore
...
PS> docker run --rm --name fix10-dn-s2 fix10-dn-lab-skiafix skia
SKBitmap 10x10

The NoDependencies variant was the one chosen for the test, and the final stage needed no extra Linux packages for it: the fixed image is the plain runtime:10.0 with the publish output copied in, no apt-get line. Put the reference in the project file itself rather than in the Dockerfile; the Dockerfile line was only the quickest way to test it. Keep its version equal to the SkiaSharp version. The fix was tested on runtime:10.0 only; the Alpine image was not tried with a native assets package.

How it was reproduced

A console app referencing SkiaSharp 3.119.0 (plus System.Drawing.Common 9.0.0 and Microsoft.Data.SqlClient for other tests in the same project), built on mcr.microsoft.com/dotnet/sdk:10.0 (SDK 10.0.302) and run on mcr.microsoft.com/dotnet/runtime:10.0 (Microsoft.NETCore.App 10.0.13) and runtime:10.0-alpine (10.0.15). Its skia mode creates a 10 by 10 SKBitmap. Docker engine 29.9.3 on Windows 11.

Frequently asked

Which package fixes libSkiaSharp not found in Docker?
In the test SkiaSharp.NativeAssets.Linux.NoDependencies 3.119.0, the same version as SkiaSharp, fixed it on the runtime:10.0 image.
Why does SkiaSharp fail in a Linux container but the build succeeds?
The managed SkiaSharp package compiles fine. The failure comes at run time, at the first native call, when libSkiaSharp.so is not in /app or the runtime folder.
Does SkiaSharp fail the same way on Alpine?
The top line was the same on runtime:10.0-alpine, with Error loading shared library lines instead of cannot open shared object file. The native assets fix was not tested on Alpine.

If you came from System.Drawing.Common: Unable to load shared library 'gdiplus.dll'. More decoded errors in the Fixes category.