This error occurs when Docker tries to relabel a bind-mounted directory for SELinux but is not allowed to do so. The fix involves removing the :z/:Z suffix, using --security-opt label:disable, or manually setting SELinux contexts.
When you mount a host directory into a Docker container on a system with SELinux enabled, Docker can optionally relabel the files to match the container's SELinux context. This is triggered by adding the `:z` (shared) or `:Z` (private) suffix to your volume mount. However, SELinux does not allow relabeling of certain system directories like `/`, `/usr`, `/etc`, or other protected paths. When you try to mount these directories with the `:z` or `:Z` flag, Docker attempts the relabel operation, SELinux blocks it, and you get this "error setting label on mount source" message. This is a security feature, not a bug. SELinux prevents relabeling of critical system directories because doing so could render your host system inoperable or create security vulnerabilities.
First, check which volume mount is causing the issue. Look at your docker run command or docker-compose.yml for mounts with :z or :Z suffixes:
# In docker run command, look for patterns like:
docker run -v /:/hostfs:z myimage
docker run -v /etc/localtime:/etc/localtime:Z myimage
# In docker-compose.yml:
volumes:
- /usr:/hostfs:z # This will fail
- /etc:/etc:Z # This will also failNote which paths are being mounted with SELinux relabel flags.
For system directories that cannot be relabeled, simply remove the SELinux suffix:
Before (fails):
docker run -v /:/hostfs:z myimageAfter (works):
docker run -v /:/hostfs myimageFor docker-compose.yml:
Before:
volumes:
- /etc/localtime:/etc/localtime:ZAfter:
volumes:
- /etc/localtime:/etc/localtime:roThe :ro (read-only) flag is often appropriate for system paths and doesn't trigger relabeling.
If your container needs write access to system directories and removing the :z flag causes permission issues, disable SELinux labeling for that container:
docker run --security-opt label:disable -v /etc:/etc myimageFor docker-compose.yml:
services:
myservice:
image: myimage
security_opt:
- label:disable
volumes:
- /etc:/etcWarning: This disables SELinux protection for that container. Only use this when necessary and understand the security implications.
Instead of mounting protected system directories, create a dedicated subdirectory:
# Instead of mounting /usr:
mkdir -p /data/app-files
docker run -v /data/app-files:/app:z myimage
# Instead of mounting root filesystem:
mkdir -p /data/hostdata
cp -r /needed/files /data/hostdata/
docker run -v /data/hostdata:/hostdata:z myimageThis allows SELinux relabeling to work properly since /data is not a protected path.
For directories you control, you can set the SELinux context manually instead of using :z/:Z:
# Set the container-friendly context on your directory
sudo chcon -Rt svirt_sandbox_file_t /path/to/your/directory
# Then mount without the :z flag
docker run -v /path/to/your/directory:/app myimageTo make this permanent (survives relabels):
sudo semanage fcontext -a -t svirt_sandbox_file_t "/path/to/your/directory(/.*)?"
sudo restorecon -Rv /path/to/your/directoryTest your container starts successfully:
# Start container with corrected volume mount
docker run -v /your/path:/container/path myimage
# For docker-compose
docker-compose up -d
# Check container is running
docker psIf the container starts without the SELinux relabel error, the fix is complete.
### Understanding :z vs :Z Flags
- :z (lowercase) - Indicates the content is shared among multiple containers. Docker labels the content with a shared content label that all containers can access.
- :Z (uppercase) - Indicates the content is private to one container. Docker labels it with a unique MCS (Multi-Category Security) label specific to that container.
Using :Z on a directory and then trying to share it with another container will fail because the second container has a different MCS label.
### Which Paths Cannot Be Relabeled
SELinux protects critical system paths from relabeling:
- Root filesystem (/)
- /usr and its subdirectories
- /etc and its subdirectories
- /var (partially protected)
- Mounted filesystems (NFS, CIFS, etc.)
### Checking SELinux Status
# Check if SELinux is enabled
getenforce
# Check SELinux context of a file/directory
ls -Z /path/to/check
# Check container's SELinux context
docker inspect --format='{{.ProcessLabel}}' container_name### Running with --privileged (Not Recommended)
While --privileged can bypass this error, it's extremely dangerous:
# DON'T do this in production
docker run --privileged -v /:/hostfs myimagePrivileged containers have root-level access to the host and bypass all security controls. Only use for debugging or specific trusted workloads.
### Docker Daemon SELinux Configuration
Check if Docker is running with SELinux support:
docker info | grep -i selinuxIf you see selinux-enabled: true, SELinux labeling is active. This can be disabled in /etc/docker/daemon.json:
{
"selinux-enabled": false
}Warning: Disabling SELinux support system-wide reduces container isolation security.
### Kubernetes and SELinux
In Kubernetes, use seLinuxOptions in your pod spec or the SELinux mount option:
spec:
containers:
- name: mycontainer
securityContext:
seLinuxOptions:
type: spc_timage operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub