1. Symptom and Environment
Observed Error (container startup):
dotnet PortfolioWebsite.dll Error: Cannot load library libgssapi_krb5.so.2: no such file or directory

Environment:
- Runtime base:
mcr.microsoft.com/dotnet/aspnet:10.0(Debian) - SDK base:
mcr.microsoft.com/dotnet/sdk:10.0 - Application: ASP.NET Core 10
2. Attempt 1: Following Official Microsoft Documentation
Action taken:
Added the official suggested line to the Dockerfile build stage.
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build ... RUN apt update && apt -y upgrade libkrb5-3 RUN dotnet publish -o out ...
Build & Run:
docker build -t portfolio:v1 . docker run --rm portfolio:v1
Observed Result: Same error persists. Library still not loaded.
3. Immediate Verification — Stop Guessing, Check the Image
Instead of rebuilding repeatedly, I shelled into the final runtime image to check file existence.
docker run --rm -it portfolio:v1 /bin/bash
Inside the container:
ls -la /usr/lib/x86_64-linux-gnu/libgssapi* 2>&1
Output:
ls: cannot access '/usr/lib/x86_64-linux-gnu/libgssapi*': No such file or directory
Also checked the build stage for comparison:
docker run --rm -it mcr.microsoft.com/dotnet/sdk:10.0 /bin/bash -c "ls /usr/lib/x86_64-linux-gnu/libgssapi* 2>&1"
Output showed the file does exist in the SDK image.
Judgment: The library was installed in the build stage but did not carry over to the final stage. Multi-stage isolation confirmed.
4. Attempt 2: Check Package State — Why upgrade Did Nothing
Inside the build stage container, I checked whether libkrb5-3 was even installed:
docker run --rm -it mcr.microsoft.com/dotnet/sdk:10.0 /bin/bash -c "apt list --installed 2>/dev/null | grep krb5"
Output: (empty) — no krb5 packages installed.
Judgment: apt upgrade libkrb5-3 only upgrades existing packages. Since the package was never installed, the command executed but performed no operation. This is a semantic error, not a missing path issue.
5. Correct Fix — Install in Final Stage, Not Build
Based on findings:
- Library must reside in the final stage
- Must use
install, notupgrade - Required packages:
libkrb5-3+libgssapi-krb5-2
Final working Dockerfile (adapted from u/NotImplemented’s solution):
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /PortfolioWebsite
COPY *.sln .
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
WORKDIR /PortfolioWebsite
# ✅ Install in FINAL stage — this is where the app runs
RUN apt-get update \
&& apt-get install -y --no-install-recommends libkrb5-3 libgssapi-krb5-2 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /PortfolioWebsite/out .
EXPOSE 5142
ENTRYPOINT ["dotnet", "PortfolioWebsite.dll"]
6. Post-Fix Verification
Rebuild and verify the library now exists in the final image:
docker build -t portfolio:v2 . docker run --rm -it portfolio:v2 /bin/bash -c "ls -la /usr/lib/x86_64-linux-gnu/libgssapi*"
Expected output:
-rw-r--r-- 1 root root ... /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2
Start the container normally:
bash
docker run --rm portfolio:v2
Application starts without the library error.
7. Additional Troubleshooting Notes (From Community)
Cache invalidation (u/percoAI):
If the fix still does not work, rebuild with no cache to avoid stale layers:
docker build --no-cache -t portfolio:v2 .
Shell safety (u/Owmelicious):
Optional but recommended for better error handling inside RUN:
RUN set -euo pipefail \
&& apt-get update \
&& apt-get install -y --no-install-recommends libkrb5-3 libgssapi-krb5-2 \
&& rm -rf /var/lib/apt/lists/*
Alternative deployment (u/crackjiver):
Publish self-contained to avoid external shared libs entirely:
RUN dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true -o out
Trade-off: larger image size, no runtime dependency on system libraries.
8. Summary of Troubleshooting Commands Used
| Step | Command | Purpose |
|---|---|---|
| 1 | docker run --rm -it <image> /bin/bash | Enter final image |
| 2 | ls /usr/lib/x86_64-linux-gnu/libgssapi* | Check library existence |
| 3 | apt list --installed | grep krb5 | Verify package installation status |
| 4 | docker build --no-cache | Bypass cached layers |
| 5 | Apply install in final stage | Permanent fix |
Core takeaway: In multi-stage Docker builds, every FROM resets the filesystem. Dependencies for runtime must be installed in the final stage. Always verify with an interactive shell before assuming a package exists.
9. References
- Microsoft .NET container documentation (reference): https://learn.microsoft.com/en-us/dotnet/core/docker/build-container