Every game handles Workshop content differently, but the failures are the same five failures in a different order: the server has an item the client does not, the client has a newer version than the server, a required dependency was never listed, an author published an update nobody asked for, or the first boot ran out of disk halfway through a four-gigabyte download. Understanding the small number of mechanisms underneath - what an item id is, where SteamCMD puts things, who tells the player to download what - turns all five into things you can diagnose in a minute rather than an afternoon.
What a Workshop item actually is#
A Workshop item is a published file with a numeric id, and that number is the only identifier that matters. It is the digits after ?id= in the URL:
https://steamcommunity.com/sharedfiles/filedetails/?id=1753134636 ^^^^^^^^^^Every item belongs to exactly one game. Titles are not unique, are not stable, and are not what any config file wants. Collections are themselves published files with their own ids. So are saves, mutators and the map packs that turn out to be two items rather than one.
You can look an item up without an API key, which is a genuinely useful habit before you add something to a server:
$ curl -s -X POST \ https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/ \ -d 'itemcount=1&publishedfileids[0]=1753134636'The response carries the title, consumer_app_id, file_size and time_updated. For that id it is the Hawaii map for Unturned, app 304930, about 300 MB, last updated at a timestamp you can compare against your server's copy. Two of those four fields answer the questions people normally guess at: is this item even for the right game, and how much disk am I about to spend.
Four ways content gets onto a server#
There are only four, and knowing which one your game uses tells you where to look when something is missing.
- The server downloads it at boot from a list in its own config. You write ids into a file, the server fetches them on start. Unturned, Project Zomboid, Killing Floor 2 and Garry's Mod all work this way. Easiest, and gives you the least control over timing.
- You download it with SteamCMD and place it yourself. Arma 3, DayZ, Squad and Left 4 Dead 2 expect this. Most control, most work, and the route that needs a Steam account that owns the game.
- You upload the files by hand. The item never touches Steam on the server side. It works, and it breaks the client side, because the server has no id to advertise.
- The game does not use Steam Workshop at all. Insurgency: Sandstorm uses mod.io. ARK: Survival Ascended uses CurseForge. Minecraft uses neither. Knowing this saves an hour of looking for a Workshop page that does not exist.
| Game | How the server gets items | Where the ids go |
|---|---|---|
| Unturned | Downloads at boot | File_IDs in WorkshopDownloadConfig.json |
| Project Zomboid | Downloads at boot | WorkshopItems= plus Mods= in <server>.ini |
| Killing Floor 2 | Downloads at boot | ServerSubscribedWorkshopItems= in KFEngine.ini |
| Garry's Mod | Mounts a collection at start | +host_workshop_collection plus -authkey |
| ARK: Survival Evolved | Managed by the server | -automanagedmods plus ActiveMods= |
| Left 4 Dead 2 | SteamCMD, then addons/ | workshop_download_item 550 <id> |
| Arma 3 | SteamCMD, owning account | workshop_download_item 107410 <id>, then -mod= |
| DayZ | SteamCMD, owning account | workshop_download_item 221100 <id>, then -mod= |
| Squad | SteamCMD | workshop_download_item 393380 <id> |
Note the app ids in that last column. Workshop content belongs to the game, not to the dedicated server tool, so 107410 is Arma 3 and not the 233780 you installed the server with. This is the same distinction that catches people creating Steam game server login tokens, and it has the same cause.
Downloading items with SteamCMD#
The command takes a game app id and one item id:
$ ./steamcmd.sh +force_install_dir /srv/arma3 \ +login myspareaccount \ +workshop_download_item 107410 463939057 \ +quitThe item lands in a predictable place inside the install directory:
/srv/arma3/steamapps/workshop/ appworkshop_107410.acf what was fetched, and when content/107410/463939057/ the item itselfappworkshop_<appid>.acf is the manifest. When an item has updated on Steam and your server stubbornly keeps the old copy, deleting that file is the standard fix: the next download has no record to compare against and fetches everything again.
Three things about this command are worth knowing before you script it. Anonymous login works for some games and not others, and the games whose server tools require an owning account almost always require one here too - the error is No subscription either way. Large items time out fairly often and succeed on a second attempt, so a retry in your script is not paranoia. And the download is only half the job: Arma 3 and DayZ then want the folder renamed or symlinked to @ModName in the server root, and every mod's .bikey copied into the server's keys/ folder, or clients are rejected for an unsigned addon. SteamCMD explained covers the surrounding arguments, and DayZ server and mods has the full sequence for that game.
Collections, and what SteamCMD cannot do with them#
A collection is a published file containing a list of other published files. Players subscribe to it in one click, which is why mod lists are usually distributed as one.
SteamCMD cannot expand a collection. workshop_download_item understands single item ids and nothing else. There are two ways around that. Some games expand collections themselves - Garry's Mod's +host_workshop_collection takes a collection id and fetches its contents, covered in Garry's Mod Workshop addons and FastDL. For everything else, ask Steam:
$ curl -s -X POST \ https://api.steampowered.com/ISteamRemoteStorage/GetCollectionDetails/v1/ \ -d 'collectioncount=1&publishedfileids[0]=2521187158'The response contains a children array, one entry per item, each with its own publishedfileid. No API key is needed. Pipe that into your config file and you have expanded the collection.
Whether you should is a separate question. A collection you do not own is a mod list somebody else controls. If the owner adds an item, your server picks it up on the next restart; if they remove one, your server loses it. For a server that matters, read the collection once and pin the individual ids. For a server you and your friends run on a Thursday, the convenience wins.
Dependencies are the other collection-shaped problem. Many items list required items on their Workshop page, and neither SteamCMD nor most games resolve them for you. In Project Zomboid a shared library needs its own number in WorkshopItems and its own name in Mods, which are two different strings from two different places - Project Zomboid mods and the Workshop takes that apart properly. In Unturned a community map is frequently a terrain item plus an asset pack, and listing only the terrain gives players a world of red error text where objects should be.
How the content reaches the player#
This is where most player-facing failures live, because games differ fundamentally and nothing tells you which model you are in.
Four models, and your game uses exactly one of them:
- Steam pushes it automatically. Unturned and Project Zomboid clients are told the server's required items on connection and download them without the player doing anything. This is the best case, and it is why hand-uploading files to these servers breaks them: the server has no id to advertise.
- The player must subscribe themselves. Left 4 Dead 2 is the sharp example. The server cannot give a campaign to a player who does not have it, and there is no fast-download path for a VPK campaign. Everyone subscribes, or nobody plays.
- A launcher does it for them. DayZ players use the DayZ Launcher, which reads the mod list the server advertises, subscribes to it, and builds the matching command line. That is precisely why mod order and keys have to be right on the server: the launcher automates the client side and fails loudly when the two disagree.
- The server keeps it to itself. Server-only content - admin tools, loot spawners, logging - goes in a separate list:
-serverMod=in Arma 3,-servermod=in DayZ. Put a server-only mod in the client list and every joining player downloads something they can never use.
The rule that falls out of all four: decide for every item whether the client needs it, and put it in the right list. Most "players get kicked on join" reports are one item in the wrong one.
Updates, versions and the mid-session break#
Workshop authors publish whenever they like. Nobody asks you, and in most games nothing tells you.
What then happens depends on who updated first. The client auto-updates through Steam; the server has whatever copy it downloaded last. When the two differ, some games kick the player with a version error and some let them in and desync quietly, which is worse. A few games handle it deliberately: Unturned monitors the hosted map for changes, because the server browser uses map version numbers to test compatibility before a player connects, and when it detects one it warns players in chat and shuts the server down after a timer so a restart can pick up the new version.
Two habits prevent most of this:
- Pin the list, and update it on purpose. Take the individual item ids rather than following someone's collection, and change them when you decide to, ideally alongside a restart you announced.
- Keep a copy of the working content. Before an update, copy the
steamapps/workshop/content/<appid>/tree, or take a backup. This is also your only protection against an author unlisting or deleting an item you depend on - once it is gone from the Workshop, no new player can fetch it and your server may not be able to re-download it either. A backup nobody has restored is a hypothesis, which is the whole argument of backups that actually restore.
Game patches are the other axis. A major game update invalidates mods until their authors rebuild them, and a server set to update automatically on patch day is a server nobody can join on patch day. Turn auto-update off on a heavily modded server, write down the versions that worked, and keep what to do when a mod update breaks to hand.
Disk, boot time and first-start timeouts#
Workshop content is not small and it lives on the same volume as the server. A single large Unturned map is a few hundred megabytes; an Arma 3 mod set with ACE, CBA and an RHS pack is tens of gigabytes; a Garry's Mod collection that nobody has pruned is however large it has grown since 2019.
Three consequences follow.
First boot is slow and looks like a crash. The server starts, begins fetching several gigabytes, and prints very little while it does. If a supervisor or panel has a startup timeout, it can kill the process mid-download, which restarts it, which starts the download again. If a server seems to be crash-looping on its first start after you added mods, watch the console before you change anything - the download is usually still running. Why your game server keeps restarting covers telling a genuine restart loop from this.
Removing an item does not free the disk. Take an id out of the list and the files stay where they are indefinitely. Clearing steamapps/workshop/content/<appid>/ occasionally, or the game's own cache folder, is real housekeeping on a 20 GB plan.
Updates need headroom. SteamCMD stages downloads on the same volume it is updating, so leave 20 to 30 per cent free. A disk sized exactly to fit the content is a disk whose next update fails.
On RE:NODE each plan states its disk, and the panel graphs disk against that limit alongside memory and CPU, so a mod list quietly eating the volume is visible before it becomes an outage. Mods and plugins are uploaded by you, through the file manager or over SFTP, or fetched by the game's own Workshop support - there is no allow-list of permitted mods.
A Workshop item is code you did not write#
For maps and textures this section does not apply. For a large share of Workshop content it very much does. Garry's Mod addons contain Lua that runs on your server. Arma 3 mods contain SQF. Project Zomboid mods contain Lua. Running one is running somebody else's code with your server's privileges, on your server's data, under your server's identity.
That is a supply chain, and the usual supply-chain hygiene applies:
- Prefer items with history. An author with a three-year changelog and an issue tracker is a different risk from an account created last week.
- Keep the list short. Every item is an update you have to watch and a possible cause when something breaks. Twelve mods you chose beat forty somebody suggested.
- Read what changed. Not every line, but the changelog before you pull an update onto a live server.
- Back up before you add. Adding is the easy part; the mod that quietly rewrote your loot tables is the part with no undo.
- Be careful what you give it. If a mod has server-side code, it can read whatever the server can read - including a login token sitting in a config file.
Keeping a modded server clean goes further into the operational side. The hosting side is simple enough to state: one container per server, CPU is a hard throttle to the share bought, and at the memory limit the container is stopped and restarted clean rather than left to swap. A mod list that outgrows the plan therefore shows up as repeated restarts rather than as a server that gets slower and slower. A watcher notices that pattern too - three restarts in an hour raises a warning on the server page and opens a ticket automatically - so a crash-looping mod is not something you find out about from a player.
Troubleshooting#
Players are kicked to an error screen on join. A required item is missing from the server's list. Usually a map's asset pack, or a dependency the item's page mentions and the config does not.
The server ignores a new item id. The list is read at boot in almost every game. Restart.
An item updated on Steam and the server still has the old copy. Delete steamapps/workshop/appworkshop_<appid>.acf and restart, or delete that item's content folder.
`workshop_download_item` fails with `No subscription`. Anonymous login is not accepted for that game's Workshop. Use an account that owns the game.
`workshop_download_item` fails with a timeout. Common on large items. Run it again; a second attempt usually completes.
The mod is on disk and the game acts as though it is not. The download step and the load step are separate in most games. Project Zomboid needs the number in WorkshopItems and the name in Mods; Arma 3 needs the folder in -mod=; Garry's Mod needs it in the collection the server mounts, not merely in the client download list.
A collection changed and the server changed with it. That is what collections do. Pin the individual ids if that is not what you wanted.
Players download a mod they cannot use. A server-only mod is in the client list. Move it to -serverMod= or the equivalent.
FAQ#
Where do Workshop files end up on a server?
Under the install directory, in steamapps/workshop/content/<gameappid>/<itemid>/, with a manifest at steamapps/workshop/appworkshop_<gameappid>.acf. Games that mount content themselves often then copy or cache it somewhere of their own, such as Garry's Mod's garrysmod/cache/workshop/.
Can SteamCMD download a whole collection?
No. It only understands individual item ids. Either the game expands the collection itself, as Garry's Mod does, or you expand it through the public GetCollectionDetails web API and write the resulting ids into your config.
Do players need to subscribe to the mods my server uses?
It depends entirely on the game. Unturned and Project Zomboid push the list to clients automatically on join. Left 4 Dead 2 does not, and every player must subscribe themselves. DayZ players are handled by the DayZ Launcher. Check which model your game uses before you write the joining instructions.
Why did my server break after a mod updated?
Because the author published a new version and your server was still running the old one, or the reverse. Pin your ids, restart deliberately rather than automatically, and keep a copy of the content folder that worked so you can put it back.
Which app id do I use for Workshop downloads?
The game's, not the dedicated server tool's. Arma 3 content is 107410 even though the server installs from 233780; Left 4 Dead 2 content is 550 even though the server installs from 222860.
How much disk should I allow for mods?
More than the content, because updates stage on the same volume. Check file_size on each item through the public API before you commit, add 20 to 30 per cent headroom, and clear out content for items you have removed, because nothing deletes it for you.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.