dotnet/runtime

File.ResolveLinkTarget(String, Boolean) doesn't fully resolve a symbolic link created by Kubernetes volume mounts to its full path

Open

#118,719 opened on Aug 14, 2025

View on GitHub
 (2 comments) (0 reactions) (0 assignees)C# (17,886 stars) (5,445 forks)batch import
area-System.IOhelp wantedos-linux

Description

Description

File.ResolveLinkTarget doesn't fully resolve a symbolic link created by Kubernetes volume mounts to its full path as realpath in Linux does.

Reproduction Steps

I tried to resolve a symolic link created by Kubernetes ConfigMap Volume Mounting. I mounted a k8s ConfigMap as a volume client-config.json. This is the file structure:

/mnt/oidc/client-config $ ls -al
total 12
drwxrwxrwx    3 root     root          4096 Aug 14 07:17 .
drwxr-xr-x    4 root     root          4096 Aug 14 07:17 ..
drwxr-xr-x    2 root     root          4096 Aug 14 07:17 ..2025_08_14_07_17_19.1395403829
lrwxrwxrwx    1 root     root            32 Aug 14 07:17 ..data -> ..2025_08_14_07_17_19.1395403829
lrwxrwxrwx    1 root     root            25 Aug 14 07:17 client-config.json -> ..data/client-config.json

Expected behavior

I would expect that File.ResolveLinkTarget() returns a fully resolved path /mnt/oidc/client-config/..2025_08_14_07_17_19.1395403829/client-config.json.

Please see this command:

/mnt/oidc/client-config $ realpath /mnt/oidc/client-config/client-config.json 
/mnt/oidc/client-config/..2025_08_14_07_17_19.1395403829/client-config.json

Actual behavior

Calling the method File.ResolveLinkTarget("/mnt/oidc/client-config/client-config.json", true) returns the resolved path /mnt/oidc/client-config/..data/client-config.json.

The code snippet is quite simple:

Console.WriteLine($"The resolved path is {File.ResolveLinkTarget("/mnt/oidc/client-config/client-config.json", true)}");

Regression?

No response

Known Workarounds

I tried another library https://github.com/nemec/pathlib and its API PosixPath.Resolve() could fully resolve the symbolic link.

Configuration

.NET: 9.0.304

OS: Alpine Linux literally using mcr.microsoft.com/dotnet/sdk:9.0-alpine

Architecture: x64

Other information

This is the API doc https://learn.microsoft.com/en-us/dotnet/api/system.io.file.resolvelinktarget?view=net-9.0. It doesn't have too much behavior description.

I'm not sure whether the behavior is desired or not.

Contributor guide