Description
Description
Summary
Suspected regression from PR #11901, which added support for running createContainer hooks in CDI specs. The failure occurs in the new rootfs self-bind path added by that change: gVisor compares /var/run/.../ rootfs with the resolved /run/.../rootfs and rejects it before the gofer writes mounts to boot.
After upgrading to release-20260520.0, Kubernetes pods using runsc via containerd fail during sandbox creation. The failure appears to be in the new gofer rootfs self-bind setup added for createContainer hook
support.
The same setup worked with release-20260511.0.
Environment
- gVisor:
release-20260520.0
- Runtime:
io.containerd.runsc.v1
- Platform:
systrap
- containerd:
v2.2.2
- Host paths involve
/var/run, which resolves to /run
Symptom
Kubernetes/containerd reports:
failed to start sandbox "...": failed to create containerd task: failed to create shim task: OCI runtime create failed: creating container: cannot create sandbox: cannot read client sync file: waiting for sandbox
to start: EOF
The boot process also logs:
FATAL ERROR: Error reading mounts file: error unmarshaling mounts: unexpected end of JSON input
JSON bytes:
That seems secondary: the gofer exits before writing the mounts JSON to the boot process.
## Gofer failure
With runsc debug logs enabled:
debug = true
"debug-log" = "/tmp/runsc-debug/%ID%/%COMMAND%.log"
"debug-command" = "gofer,boot"
The gofer log shows the actual failure:
Version release-20260520.0, go1.25.5, amd64, 4 CPUs, linux, PID 1, PPID 0, UID 0, GID 0
Args: [runsc-gofer ... gofer --bundle /var/run/docker/containerd/io.containerd.runtime.v2.task/k8s.io/3668be23b5443d4ec2f2eaaec87c1d1985bfe11390c5b98b5e9cb93f6f70d802 ...]
FATAL ERROR: Error setting up root FS: self-bind-mounting rootfs "/var/run/docker/containerd/io.containerd.runtime.v2.task/k8s.io/3668be23b5443d4ec2f2eaaec87c1d1985bfe11390c5b98b5e9cb93f6f70d802/rootfs" for hooks:
failed to safely mount: expected to open /var/run/docker/containerd/io.containerd.runtime.v2.task/k8s.io/3668be23b5443d4ec2f2eaaec87c1d1985bfe11390c5b98b5e9cb93f6f70d802/rootfs, but found /run/docker/containerd/
io.containerd.runtime.v2.task/k8s.io/3668be23b5443d4ec2f2eaaec87c1d1985bfe11390c5b98b5e9cb93f6f70d802/rootfs
Suspected cause
/var/run is a symlink to /run.
The bundle/rootfs path passed to runsc is under:
/var/run/docker/containerd/...
But when gVisor opens/checks the path, it observes the resolved path:
/run/docker/containerd/...
The new safe mount check appears to compare the unresolved input path against the resolved opened path and treats this as a mismatch.
This seems related to the new rootfs self-bind logic introduced between release-20260511.0 and release-20260520.0, especially:
ae18a84df
Describe the results you received and expected
Expected behavior
runsc should accept equivalent canonical paths where /var/run resolves to /run, or canonicalize both paths before enforcing the safe mount check.
Alternatively, if createContainer hooks are not present, the new rootfs self-bind path probably should not cause sandbox creation to fail.
Actual behavior
Sandbox creation fails before the gofer writes mounts to the boot process. The boot process then reports an empty mounts JSON error.
Workaround
Pinning back to release-20260511.0 avoids the issue.
Another possible workaround may be ensuring containerd/runsc consistently use /run/docker/containerd/... instead of /var/run/docker/containerd/..., but that is not always easy to control from higher-level
Kubernetes/runtime configuration.
Additional notes
This reproduces across multiple pods and with both overlayfs and stargz snapshotters, so it does not appear to be image-specific or snapshotter-specific.
What version of containerd are you using?
2.2.2
Description
Description
Summary
Suspected regression from PR #11901, which added support for running createContainer hooks in CDI specs. The failure occurs in the new rootfs self-bind path added by that change: gVisor compares /var/run/.../ rootfs with the resolved /run/.../rootfs and rejects it before the gofer writes mounts to boot.
After upgrading to
release-20260520.0, Kubernetes pods usingrunscvia containerd fail during sandbox creation. The failure appears to be in the new gofer rootfs self-bind setup added for createContainer hooksupport.
The same setup worked with
release-20260511.0.Environment
release-20260520.0io.containerd.runsc.v1systrapv2.2.2/var/run, which resolves to/runSymptom
Kubernetes/containerd reports:
Suspected cause
/var/run is a symlink to /run.
The bundle/rootfs path passed to runsc is under:
/var/run/docker/containerd/...
But when gVisor opens/checks the path, it observes the resolved path:
/run/docker/containerd/...
The new safe mount check appears to compare the unresolved input path against the resolved opened path and treats this as a mismatch.
This seems related to the new rootfs self-bind logic introduced between release-20260511.0 and release-20260520.0, especially:
ae18a84df
Describe the results you received and expected
Expected behavior
runsc should accept equivalent canonical paths where /var/run resolves to /run, or canonicalize both paths before enforcing the safe mount check.
Alternatively, if createContainer hooks are not present, the new rootfs self-bind path probably should not cause sandbox creation to fail.
Actual behavior
Sandbox creation fails before the gofer writes mounts to the boot process. The boot process then reports an empty mounts JSON error.
Workaround
Pinning back to release-20260511.0 avoids the issue.
Another possible workaround may be ensuring containerd/runsc consistently use /run/docker/containerd/... instead of /var/run/docker/containerd/..., but that is not always easy to control from higher-level
Kubernetes/runtime configuration.
Additional notes
This reproduces across multiple pods and with both overlayfs and stargz snapshotters, so it does not appear to be image-specific or snapshotter-specific.
What version of containerd are you using?
2.2.2