OS Name/Version:
Debian 12.13
Product Name/Version:
AMP version: 2.7.2.2 - 20260429.1
Docker Engine version: 29.4.2
Docker API version: 1.54
containerd: v2.2.3
runc: 1.3.5
Problem Description:
After Docker updated to 29.4.2, SteamCMD inside AMP Docker containers started failing with:
CreateBoundSocket: failed to create socket, error [no name available] (38)
This caused AMP game server updates/installs to fail. In my case this affected a Windrose instance running inside an AMP-created Docker container.
Example container:
AMP_Windrose01 cubecoders/ampbase:wine-stable
Docker was using the built-in seccomp profile before the workaround:
Security Options:
apparmor
seccomp
Profile: builtin
Steps to reproduce:
Step 1
Use AMP on Debian 12 with Docker Engine 29.4.2.
Step 2
Create or update a game server instance that uses SteamCMD inside an AMP Docker container.
Step 3
Run Update on the instance.
Step 4
SteamCMD fails with:
CreateBoundSocket: failed to create socket, error [no name available] (38)
Actions taken to resolve so far:
I found that Docker 29.4.2 appears to block the syscall path SteamCMD needs inside the AMP container. I worked around it by using a custom Docker seccomp profile based on Docker/Moby’s default profile, with two targeted changes:
Allow AF_ALG socket family 38
Allow 32-bit x86 socketcall
This is not seccomp=unconfined. Seccomp remains enabled:
Seccomp: 2
Seccomp_filters: 1
Security note:
This workaround intentionally makes Docker’s seccomp profile less restrictive than the current built-in profile. AF_ALG was blocked by Docker as a mitigation for CVE-2026-31431 / “Copy Fail”, a Linux kernel local privilege-escalation issue involving the algif_aead / AF_ALG crypto API.
So this should not be described as having “no security issues.”
My understanding is:
Vulnerable host kernel + AF_ALG allowed = risky
Patched host kernel + AF_ALG allowed = much less concerning
Vulnerable host kernel + AF_ALG blocked = mitigated by Docker's seccomp profile
This should be treated as a temporary workaround until Docker/CubeCoders provides an official fix.
————————————————————————————————————————
The workaround steps I used are below.
Docker 29.4.2 SteamCMD / AMP CreateBoundSocket Fix
Disclaimer: I am not responsible if this breaks your server, Docker setup, AMP install, containers, game saves, network config, or anything else. This is just what fixed the issue on my Debian 12 AMP host. Read the commands first, make backups, and use at your own risk.
Problem
After updating Docker to 29.4.2, SteamCMD inside CubeCoders AMP Docker containers started failing with errors like:
CreateBoundSocket: failed to create socket, error [no name available] (38)
In AMP, this caused SteamCMD updates/installs to fail. Example affected flow:
Loading Steam API...CreateBoundSocket: failed to create socket, error [no name available] (38)
OK
force_install_dir "4129620"
Connecting anonymously to Steam Public...Retrying...
CreateBoundSocket: failed to create socket, error [no name available] (38)
Retrying...
Scope
This workaround is for a Docker/seccomp issue affecting SteamCMD inside AMP Docker containers.
The relevant issue is:
Docker 29.4.2 + seccomp + SteamCMD inside AMP containers
This guide assumes a normal AMP Docker setup using CubeCoders’ Wine stable base image, for example:
cubecoders/ampbase:wine-stable
Security note
This workaround intentionally makes Docker’s seccomp profile less restrictive than the current built-in profile.
The important change is that it re-allows:
AF_ALG socket family 38
32-bit x86 socketcall
Docker blocked AF_ALG as a mitigation for CVE-2026-31431 / “Copy Fail”, a Linux kernel local privilege-escalation issue involving the algif_aead / AF_ALG crypto API.
So I do not describe this workaround as having “no security issues.”
A more accurate way to think about it is:
Vulnerable host kernel + AF_ALG allowed = risky
Patched host kernel + AF_ALG allowed = much less concerning
Vulnerable host kernel + AF_ALG blocked = mitigated by Docker's seccomp profile
If your host kernel has been patched for CVE-2026-31431 and you have rebooted into the patched kernel, the specific known exploit risk should be greatly reduced. However, this custom profile still gives containers broader syscall access than Docker’s hardened built-in profile.
Use this as a temporary workaround, especially on trusted/self-hosted game servers. Avoid running random untrusted containers while this workaround is active. Once Docker/CubeCoders provides an official fix, remove the custom profile and return to Docker’s built-in seccomp profile.
Check the currently running kernel with:
uname -r
On Debian, also check what kernel package is installed/candidate with:
apt policy linux-image-amd64
Remember: installing a patched kernel package is not enough by itself. You need to reboot into the patched kernel.
Host / Environment
This was tested on:
Debian 12
Docker Engine 29.4.2
CubeCoders AMP
AMP game instance using cubecoders/ampbase:wine-stable
Kernel: 6.1.0-44-amd64
Before the fix, Docker showed the default built-in seccomp profile:
docker info | grep -A5 "Security Options"
Output:
Security Options:
apparmor
seccomp
Profile: builtin
What fixed it
The workaround was to use a custom Docker seccomp profile based on Docker/Moby’s default profile, but with two targeted changes:
- Allow
AF_ALGsockets. - Allow the old 32-bit
socketcallsyscall path.
This keeps seccomp enabled. It is not the same as running containers with:
seccomp=unconfined
After the fix, Docker showed:
Security Options:
apparmor
seccomp
Profile: /etc/docker/seccomp/default-plus-afalg.json
cgroupns
Docker also prints this warning:
WARNING: daemon is not using the default seccomp profile
That warning is expected because a custom profile is being used.
Step 1 — Back up existing Docker daemon config
sudo mkdir -p /root/docker-seccomp-backup
sudo cp -a /etc/docker/daemon.json \
/root/docker-seccomp-backup/daemon.json.backup.$(date +%F-%H%M%S) \
2>/dev/null || true
Step 2 — Create seccomp profile directory
sudo mkdir -p /etc/docker/seccomp
Step 3 — Download Docker/Moby default seccomp profile
sudo curl -fsSL \
https://raw.githubusercontent.com/moby/profiles/main/seccomp/default.json \
-o /etc/docker/seccomp/default-plus-afalg.json
Verify it downloaded:
ls -lh /etc/docker/seccomp/default-plus-afalg.json
Step 4 — Add AF_ALG socket allow rule
AF_ALG is socket family number 38.
sudo python3 - <<'PY'
import json
from pathlib import Path
path = Path("/etc/docker/seccomp/default-plus-afalg.json")
with path.open("r") as f:
profile = json.load(f)
rule = {
"names": ["socket"],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ"
}
]
}
syscalls = profile["syscalls"]
already = False
for entry in syscalls:
if entry.get("names") == ["socket"] and entry.get("action") == "SCMP_ACT_ALLOW":
for arg in entry.get("args", []):
if arg.get("index") == 0 and arg.get("value") == 38 and arg.get("op") == "SCMP_CMP_EQ":
already = True
if not already:
insert_at = 0
for i, entry in enumerate(syscalls):
if entry.get("names") == ["socket"]:
insert_at = i
break
syscalls.insert(insert_at, rule)
with path.open("w") as f:
json.dump(profile, f, indent=2)
print("Done. AF_ALG socket allow rule is present.")
PY
Validate JSON:
python3 -m json.tool /etc/docker/seccomp/default-plus-afalg.json >/dev/null && echo "JSON OK"
Expected:
JSON OK
Step 5 — Allow old 32-bit socketcall
This was the missing part in my case.
SteamCMD was still failing even after AF_ALG tested OK inside the container. The reason appears to be that some older/32-bit SteamCMD code paths can still hit socketcall, and Docker’s seccomp profile was returning errno 38.
Back up the profile first:
sudo cp -a /etc/docker/seccomp/default-plus-afalg.json \
/root/docker-seccomp-backup/default-plus-afalg.before-socketcall.$(date +%F-%H%M%S).json
Patch the socketcall rule:
sudo python3 - <<'PY'
import json
from pathlib import Path
path = Path("/etc/docker/seccomp/default-plus-afalg.json")
with path.open("r") as f:
profile = json.load(f)
changed = False
for entry in profile["syscalls"]:
if entry.get("names") == ["socketcall"]:
entry["action"] = "SCMP_ACT_ALLOW"
entry.pop("errnoRet", None)
entry["includes"] = {"arches": ["x86"]}
changed = True
if not changed:
profile["syscalls"].insert(0, {
"names": ["socketcall"],
"action": "SCMP_ACT_ALLOW",
"includes": {"arches": ["x86"]}
})
with path.open("w") as f:
json.dump(profile, f, indent=2)
print("Done. socketcall is now allowed for 32-bit x86 processes.")
PY
Validate JSON again:
python3 -m json.tool /etc/docker/seccomp/default-plus-afalg.json >/dev/null && echo "JSON OK"
Step 6 — Configure Docker to use the custom profile
This edits /etc/docker/daemon.json without wiping other existing settings.
sudo python3 - <<'PY'
import json
from pathlib import Path
path = Path("/etc/docker/daemon.json")
if path.exists() and path.stat().st_size > 0:
with path.open("r") as f:
data = json.load(f)
else:
data = {}
data["seccomp-profile"] = "/etc/docker/seccomp/default-plus-afalg.json"
with path.open("w") as f:
json.dump(data, f, indent=2)
print(json.dumps(data, indent=2))
PY
Validate Docker daemon config JSON:
python3 -m json.tool /etc/docker/daemon.json
Expected to contain:
{
"seccomp-profile": "/etc/docker/seccomp/default-plus-afalg.json"
}
If your daemon config already had other settings, those should still be present too.
Step 7 — Restart Docker
Stop AMP/game instances first if possible.
sudo systemctl restart docker
Check Docker came back:
sudo systemctl status docker --no-pager
Confirm the custom seccomp profile is loaded:
docker info | grep -A5 "Security Options"
Expected:
Security Options:
apparmor
seccomp
Profile: /etc/docker/seccomp/default-plus-afalg.json
cgroupns
Again, this warning is expected:
WARNING: daemon is not using the default seccomp profile
Step 8 — Recreate the affected AMP game container
This part mattered.
Existing AMP containers may not pick up the changed Docker seccomp profile until the container wrapper is recreated.
List containers:
docker ps -a --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}'
Example:
CONTAINER ID NAMES IMAGE STATUS
aff398977831 AMP_Windrose01 cubecoders/ampbase:wine-stable Up 12 seconds
Stop the affected instance in AMP first.
Then remove only the Docker container wrapper:
docker rm AMP_Windrose01
Replace AMP_Windrose01 with your actual AMP container name.
Do not delete the AMP instance itself.
Start the instance again from AMP. AMP should recreate the container using the new Docker daemon seccomp profile.
Step 9 — Verify seccomp and AF_ALG inside the AMP container
Check seccomp is still enabled:
docker exec AMP_Windrose01 grep Seccomp /proc/self/status
Expected:
Seccomp: 2
Seccomp_filters: 1
Check AF_ALG socket creation:
docker exec -i AMP_Windrose01 python3 - <<'PY'
import socket
try:
s = socket.socket(38, socket.SOCK_SEQPACKET, 0)
print("AF_ALG socket OK")
s.close()
except Exception as e:
print("AF_ALG socket FAILED:", repr(e))
PY
Expected:
AF_ALG socket OK
Check Docker is using the custom profile:
docker info | grep -A5 "Security Options"
Expected:
Security Options:
apparmor
seccomp
Profile: /etc/docker/seccomp/default-plus-afalg.json
cgroupns
Result after fix
After applying the profile and recreating the AMP container, SteamCMD worked again. The important part is that the old CreateBoundSocket error disappeared and SteamCMD could connect to Steam Public.
Successful AMP update log:
Loading Steam API...OK
force_install_dir "4129620"
Connecting anonymously to Steam Public...OK
Waiting for client config...OK
Waiting for user info...OK
@sSteamCmdForcePlatformType windows
"@sSteamCmdForcePlatformType" = "windows"
app_update 4129620 validate
Update state (0x5) verifying install, progress: 48.09 (1462470440 / 3041100240)
Update state (0x5) verifying install, progress: 96.87 (2945959199 / 3041100240)
Update state (0x0) unknown, progress: 0.00 (0 / 0)
Success! App '4129620' fully installed.
quit
Unloading Steam API...OK
It also successfully installed Steam app 1007:
app_update 1007 validate
Success! App '1007' fully installed.
Rollback / Undo
If Docker releases a fixed version and you want to go back to Docker’s built-in seccomp profile, remove the custom profile entry from /etc/docker/daemon.json.
sudo python3 - <<'PY'
import json
from pathlib import Path
path = Path("/etc/docker/daemon.json")
if not path.exists():
raise SystemExit("No /etc/docker/daemon.json exists.")
with path.open("r") as f:
data = json.load(f)
data.pop("seccomp-profile", None)
with path.open("w") as f:
json.dump(data, f, indent=2)
print(json.dumps(data, indent=2))
PY
Validate JSON:
python3 -m json.tool /etc/docker/daemon.json
Restart Docker:
sudo systemctl restart docker
Confirm Docker is back to the built-in profile:
docker info | grep -A5 "Security Options"
Expected:
Security Options:
apparmor
seccomp
Profile: builtin
You may also need to recreate any AMP containers again after reverting so they pick up the built-in profile.
Notes
- This is safer than
seccomp=unconfinedbecause seccomp remains enabled. - The custom profile is based on Docker/Moby’s default profile.
- The two important changes were:
- Allow
AF_ALGsocket family38. - Allow
socketcallfor 32-bit x86 processes.
- Allow
- This fixed SteamCMD inside a
cubecoders/ampbase:wine-stableAMP container for me. - Existing containers may need to be recreated after changing Docker’s daemon-level seccomp profile.
- If the host kernel is patched for CVE-2026-31431 and the system has rebooted into that patched kernel, the known
AF_ALGexploit risk should be greatly reduced. - Even on a patched kernel, this should still be treated as a temporary workaround until Docker/CubeCoders provides an official fix.