If you run Docker inside LXC containers on Proxmox you probably woke up this week to a fun surprise. Your containers won’t start anymore. The error looks like this:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied: unknown
This isn’t a Proxmox bug. It’s not even really a Docker bug. It’s a security patch that landed in containerd.io version 1.7.28-2 around November 5th fixing CVE-2025-52881, a critical container escape vulnerability. The fix involves reopening fil…
If you run Docker inside LXC containers on Proxmox you probably woke up this week to a fun surprise. Your containers won’t start anymore. The error looks like this:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied: unknown
This isn’t a Proxmox bug. It’s not even really a Docker bug. It’s a security patch that landed in containerd.io version 1.7.28-2 around November 5th fixing CVE-2025-52881, a critical container escape vulnerability. The fix involves reopening file descriptors for procfs operations which triggers AppArmor permission errors when running Docker inside nested LXC containers.
The technical details are actually kind of fascinating. Bear with me, I’ll make it as simple as I can.
A detached mount is a filesystem mount that exists in the kernel but isn’t attached to any path in the filesystem tree. Think of it like a mounted filesystem that’s floating in memory without a mountpoint.
Normally when you mount something, it gets attached to a specific path thus:
mount /dev/sda1 /mnt/data # attached to /mnt/data
A detached mount exists but has no path. You can only access it through file descriptors. Runc uses detached mounts as a security feature to avoid race conditions where an attacker could swap out mountpoints while runc is trying to access them.
The problem is that when the kernel tries to generate a pathname for files inside a detached mount (which AppArmor needs since it’s path-based), it can only see the relative path from the mount root. So /proc/sys/net/ipv4/ip_unprivileged_port_start inside a detached procfs mount just looks like /sys/net/ipv4/ip_unprivileged_port_start to AppArmor because the /proc part doesn’t exist in the filesystem tree.
It’s basically a mismatch between two security features: runc’s use of detached mounts to prevent path-based attacks, and AppArmor’s path-based access control system that needs actual paths to make decisions.
In case you were curious, SELinux wouldn’t have this problem because it’s label-based rather than path-based.
SELinux assigns security labels (contexts) directly to files, processes, and other objects. When you access a file, SELinux checks if your process label is allowed to perform that action on the file’s label.
How we do fix this?
There are a few ways to fix this. You could disable AppArmor entirely for the container by adding lxc.apparmor.profile: unconfined to your LXC config file, but that feels like overkill. I am, after all, using the supported and blessed path of not running a container on the host so I shouldn’t have to do this.
Probably the best solution, at least for now, is adding lxc.sysctl.net.ipv4.ip_unprivileged_port_start=0 to your LXC container configuration at /etc/pve/lxc/<CTID>.conf and restarting the container. This allows the sysctl setting that Docker needs without completely disabling security features.
AppArmor, you are making this hard
Look, I get it. AppArmor exists for good reasons. It provides mandatory access control and helps contain potential security issues. But for homelab users and small deployments this stuff is beginning to get exhausting. This is not my first frustration with AppArmor since adopting Proxmox 9 a few months ago. The enterprise folks have teams to deal with this crap, the rest of us are just trying to run some containers.
Proxmox is genuinely great software. And I have made countless videos both at work and personally about it. The team does excellent work and the platform is rock solid for virtualization. But the AppArmor integration continues to be a source of friction that makes recommending it harder than it should be. I’m going to have to start to look for alternatives soon, not that there really are any. Ugh.