System.IO.FileNotFoundException: Could not find file '/app/data\patients.json'.
in a Linux container means the code built the path with a backslash. On Linux the
backslash is part of the file name, not a separator. Build the path with
Path.Combine or a forward slash.
In the test, File.ReadAllText(Path.Combine("data", "patients.json")) read the
same file that "data\\patients.json" could not find.
The error
PS> docker run --rm --name fix10-dn-f1 fix10-dn-lab file
Unhandled exception. System.IO.FileNotFoundException: Could not find file '/app/data\patients.json'.
File name: '/app/data\patients.json'
...
at System.IO.File.ReadAllText(String path, Encoding encoding)
at Program.<Main>$(String[] args) in /src/Program.cs:line 10
Why it happens
Line 10 was File.ReadAllText("data\\patients.json"), the Windows way of writing it.
In the container the working folder is /app, so the relative path became
/app/data\patients.json: one file name with a backslash in it, inside
/app. The file is there, under its folder:
PS> docker run --rm --name fix10-dn-f4 --entrypoint ls fix10-dn-lab -l /app/data
total 4
-rwxr-xr-x 1 root root 94 Nov 13 05:30 patients.json
The message itself shows the mix: forward slashes from the working folder, then one
backslash from the code. That mix is the sign to look for. Read the path in the message
before anything else: it is the full path the runtime tried, so it also shows which
folder a relative path was resolved against. Here that was /app, the
WORKDIR of the final stage.
The second line of the message, File name: '/app/data\patients.json', shows
the backslash as well. Both failing runs in this post exited with code 139 and named
the ReadAllText line of Program.cs (line 10 and line 14); the
fixed call on the same image printed the file's contents.
The fix
Console.WriteLine(File.ReadAllText(Path.Combine("data", "patients.json")));
PS> docker run --rm --name fix10-dn-f3 fix10-dn-lab filefix
[{"name":"Maria Garcia","phone":"+00-555-0101"},{"name":"David Chen","phone":"+00-555-0102"}]
Path.Combine joins the two parts without a hard-coded separator in the code,
and in the container it read the file that the backslash version could not find.
The second cause: letter case
The same exception came from a forward-slash path whose file name differed only in case:
the code asked for Patients.json, the file is patients.json.
PS> docker run --rm --name fix10-dn-f2 fix10-dn-lab filecase
Unhandled exception. System.IO.FileNotFoundException: Could not find file '/app/data/Patients.json'.
File name: '/app/data/Patients.json'
...
The fix is the exact name as ls prints it, so compare the names in the code
with the files in the image, not with the files in your project folder.
How it was reproduced
A console app built on mcr.microsoft.com/dotnet/sdk:10.0 (SDK 10.0.302) with
data/patients.json published next to the DLL
(CopyToPublishDirectory="PreserveNewest"), run on
mcr.microsoft.com/dotnet/runtime:10.0 (Microsoft.NETCore.App 10.0.13) with
WORKDIR /app. Docker engine 29.9.3 on Windows 11. The names in the data file
are fictional.
Frequently asked
- Why does my .NET app find the file on Windows but not in Docker?
- In the test the code used data\patients.json. In the Linux container that became one file name with a backslash in it, /app/data\patients.json, which does not exist.
- How do I build file paths that work on Windows and Linux in C#?
- Use Path.Combine("data", "patients.json"). It read the file in the Linux container where the backslash path failed.
- Are file names case sensitive in a .NET Linux container?
- In the test, asking for Patients.json when the file was patients.json threw FileNotFoundException. Use the exact name shown by ls in the container.
More decoded errors in the Fixes category.