Add fix-couldnt-allocate-server-ip-port/en.md
Browse Source
1 changed file
with 13 additions and 0 deletions
fix-couldnt-allocate-server-ip-port/en.md
A
| @@ -0,0 +1,13 @@ | ||
| 1 | +--- | |
| 2 | +title: "Fix: 'Couldn't allocate dedicated server IP port' (Address in Use)" | |
| 3 | +excerpt: "The two things behind this startup error: the UDP port is already held by another process, or the +ip you gave is not an address on the machine." | |
| 4 | +category: "errors" | |
| 5 | +tags: "ports, bind" | |
| 6 | +image: "" | |
| 7 | +read_time: "8 min read" | |
| 8 | +--- | |
| 9 | +<p>The server refuses to start and prints:</p><pre>Couldn't allocate dedicated server IP port</pre><p>The engine could not bind its UDP socket. There are only two real causes: the port is already in use by another process, or the <code>+ip</code> you asked it to bind is not an address the machine actually has. This walks both down, with the commands to find the offending process and the correct way to run several servers on one box.</p><h2>1. Find what is holding the port</h2><p>The default is UDP 27015. Check who owns it on Linux:</p><pre>ss -ulpn | grep 27015</pre><p>or, if <code>ss</code> is unavailable:</p><pre>netstat -ulpn | grep 27015</pre><p>A line here means another process — usually a previous HLDS instance that did not exit cleanly — still holds the socket. On Windows the equivalent is <code>netstat -ano | findstr 27015</code> to get the PID.</p><h2>2. Kill the stale instance</h2><p>If the culprit is an old server that hung, stop it. Take the PID from the previous command:</p><pre>kill 12345 | |
| 10 | +# if it will not die: | |
| 11 | +kill -9 12345</pre><p>This is the most common case after a crash: the process is gone from your view but the kernel still has the socket bound for a moment, or a zombie <code>hlds</code> is genuinely still running. Confirm the port is free — the <code>ss</code> command returns nothing — then start the server. An auto-restart wrapper that does not check for a running instance can also spawn a duplicate; see <a href="/tutorials/auto-restart-on-crash">auto-restart on crash</a>.</p><h2>3. Check the +ip you passed</h2><p>The other cause is a bad <code>+ip</code>. The engine can only bind an address that exists on the machine. If your start line says <code>+ip 203.0.113.9</code> but that IP is not configured on any interface, the bind fails with the same error. List the machine's addresses:</p><pre>ip addr show</pre><p>Use an address that appears there, or drop <code>+ip</code> entirely to bind all interfaces. On a VPS with one public IP, omitting <code>+ip</code> is usually correct.</p><h2>4. Running several servers: give each its own port</h2><p>Two servers on the same box cannot share a port. Assign each a distinct <code>+port</code>:</p><pre>./hlds_run -game cstrike +ip 0.0.0.0 +port 27015 +map de_dust2 | |
| 12 | +./hlds_run -game cstrike +ip 0.0.0.0 +port 27016 +map de_inferno</pre><p>Remember CS 1.6 uses UDP, and the client connects to that exact port. Open each port in the firewall — see <a href="/tutorials/cs16-server-firewall-ports">server firewall ports</a> — and give each instance its own game directory as described in <a href="/tutorials/multiple-cs16-servers-one-vps">running multiple servers on one VPS</a>.</p><h2>5. Handle the restart race cleanly</h2><p>The most frustrating version of this error appears only intermittently, right after a crash-restart. What happens is that the old process has died but the kernel holds its UDP socket in a brief teardown state, and a restart script that relaunches instantly hits the port before it is released. The fix is to make the restart wait for the port to actually be free rather than firing on a fixed timer. A simple loop that checks the port before starting is enough:</p><pre>while ss -ulpn | grep -q :27015; do sleep 1; done | |
| 13 | +./hlds_run -game cstrike +port 27015 +map de_dust2</pre><p>This waits until nothing holds 27015, then starts, so the allocation never races the release. Build the same check into a systemd unit or a supervisor script and the intermittent version of this error disappears entirely — the guidance in <a href="/tutorials/auto-restart-on-crash">auto-restart on crash</a> covers wiring it into a proper restart loop.</p><h2>Common errors</h2><ul><li><strong>Error after a crash</strong> — the previous process still holds the port. Find and kill it, then start.</li><li><strong>Error with a specific +ip</strong> — that address is not on the machine. Use one from <code>ip addr</code> or omit <code>+ip</code>.</li><li><strong>Second server fails, first is fine</strong> — both use 27015. Give the second a different <code>+port</code>.</li><li><strong>Works once, fails on restart</strong> — the restart script relaunches before the old socket releases; add a short wait or an instance check.</li><li><strong>Binds but is unreachable</strong> — that is a firewall problem, not this error; the port bound but traffic is blocked.</li></ul><h2>Verification</h2><p>Before starting, run <code>ss -ulpn | grep 27015</code> and confirm nothing is listed — the port is free. Start the server and watch the console reach map load without the allocation error. Then from another machine, confirm the server answers on that UDP port — it appears in the browser or responds to a query. If it starts clean and answers, the socket bound correctly. If the error returns on the next restart, your relaunch is racing the socket release.</p> | |
| 0 | 14 |









