How to Install SteamCMD on Linux for HLDS

March 12, 2026 Daemon666 8 min read 10 views

SteamCMD is Valve's command-line content downloader — the tool you use to install and update a Half-Life Dedicated Server (HLDS) and CS 1.6, which is Steam app 90. It runs anonymously (no Steam login needed for HLDS) and is the foundation under every CS 1.6 install method, including panels and LinuxGSM. This guide installs SteamCMD on a Linux box and uses it to pull down CS 1.6.

1. Create a non-root user

Never run SteamCMD or a game server as root. Create a service account:

sudo adduser steam
sudo su - steam

Do the rest as this user, in its home directory.

2. Install the 32-bit dependencies

SteamCMD and the CS 1.6 engine are 32-bit. On a 64-bit Debian/Ubuntu host you must enable the i386 architecture and install the 32-bit C runtime, or SteamCMD will not run:

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y lib32gcc-s1 lib32stdc++6 ca-certificates

On older releases the package is lib32gcc1 rather than lib32gcc-s1; install whichever your distro provides. On CentOS/RHEL the equivalents are glibc.i686 and libstdc++.i686.

3. Download and extract SteamCMD

Fetch the official tarball from Valve's CDN and unpack it:

mkdir ~/steamcmd && cd ~/steamcmd
wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
tar -xvzf steamcmd_linux.tar.gz

That leaves steamcmd.sh in the directory. The first time you run it, SteamCMD downloads its own updates before giving you a prompt — that is normal.

4. Run SteamCMD and log in anonymously

./steamcmd.sh

At the Steam> prompt, log in anonymously — HLDS (app 90) is available without an account:

login anonymous

You should see Waiting for user info...OK. If it hangs here, it is almost always the missing 32-bit libraries from step 2.

5. Download CS 1.6 (app 90)

Set the install directory first, then update the app. Order matters — force_install_dir must come before app_update:

force_install_dir /home/steam/hlds
app_update 90 validate
quit

app_update 90 validate downloads CS 1.6 and verifies every file. This is the single command at the heart of every CS 1.6 install. App 90 is known to sometimes report success with an incomplete cstrike folder; if that happens, run app_update 90 validate again — it resumes and fills the gaps rather than re-downloading everything.

6. Do it all in one non-interactive line

For scripts and cron, pass the same commands as arguments so SteamCMD runs unattended:

./steamcmd.sh +login anonymous +force_install_dir /home/steam/hlds +app_update 90 validate +quit

This is exactly what LinuxGSM and Pterodactyl eggs run under the hood. To update the server later, run the same line again — it only downloads changed files.

7. Keep SteamCMD and the server separate

Install SteamCMD in its own directory (~/steamcmd) and the game in another (~/hlds), as the commands above do. Mixing them means a SteamCMD self-update can overwrite server files, and it makes backups messier. Keeping them apart also lets you run one SteamCMD against several install directories — just change force_install_dir per invocation. When Valve pushes a CS 1.6 update, stop the server, re-run the non-interactive line from step 6, and start it again; because validate checks every file, it also repairs a server whose files were corrupted by a bad shutdown or a full disk.

Troubleshooting

  • "steamcmd.sh: No such file or directory" though it exists — the 32-bit loader is missing. Install lib32gcc-s1/lib32stdc++6; a 32-bit binary on a 64-bit host with no i386 libs fails this way.
  • Hangs at "Waiting for user info..." — same missing 32-bit libraries, or no outbound network. Confirm the deps and that the host can reach Steam's CDN.
  • "ERROR! Failed to install app '90' (Missing file permissions)" — the install dir is not writable by the steam user, or you ran an earlier step as root and left root-owned files. Fix ownership with chown -R steam:steam /home/steam/hlds.
  • cstrike folder incomplete after "Success" — a known app-90 quirk. Re-run app_update 90 validate.
  • force_install_dir ignored — you put it after app_update. It must come first.

Verification

Confirm the download landed:

ls /home/steam/hlds/hlds_run
ls /home/steam/hlds/cstrike/maps/de_dust2.bsp

Both should exist. Then launch the server to prove the files are complete:

cd /home/steam/hlds
./hlds_run -game cstrike +map de_dust2 +maxplayers 12

If it reaches Console initialized and loads the map, SteamCMD did its job. From here, configure the server with the full Linux dedicated-server guide, or hand the whole lifecycle to LinuxGSM, which wraps this exact SteamCMD flow.

Contributors: Daemon666 ✦
Share: