In short: host the pack's .zip at a direct HTTPS link, put the link in resource-pack and the archive's SHA-1 in resource-pack-sha1, in lowercase. If nobody should play without it, set require-resource-pack=true. Restart the server: server.properties is only read at startup. Updated the archive? Compute the SHA-1 again.
server.properties keys
| Key | Default | What it does |
|---|---|---|
resource-pack | empty | The link to the pack's ZIP archive. Empty means no pack. 250 MiB at most |
resource-pack-sha1 | empty | The archive's SHA-1 in lowercase hexadecimal. Optional but recommended: it's used to verify the pack's integrity |
require-resource-pack | false | true disconnects a player who declines the pack |
resource-pack-prompt | empty | Your own text in the pack prompt; empty means the default one. Expects text component syntax |
resource-pack-id | empty | An optional UUID that identifies the pack to clients (since 1.20.3) |
resource-pack=https://files.example.com/packs/server-pack.zip
resource-pack-sha1=0123456789abcdef0123456789abcdef01234567
require-resource-pack=trueWhat kind of link you need
- A direct link to the ZIP. The address must return the archive itself, not a file-sharing page with a "Download" button. Test it: opened in a browser, the link should download the
.zipstraight away. - HTTP or HTTPS. Each player's client downloads the pack, not the server, so the host must be reachable from the internet and cope with downloads when many players join at once.
- 250 MiB at most. The smaller the archive, the sooner a player is in the game.
- The archive is the pack.
pack.mcmetamust sit at the ZIP's root. The format number for your version is in the table in data packs: resource packs use the samemin_formatandmax_formatscheme.
How to compute the SHA-1
A SHA-1 is 40 hexadecimal characters. Per the protocol description on the Minecraft Wiki, if the string doesn't look like such a hash, the client can't verify the file and will likely waste bandwidth. Hash the same archive that sits behind the link:
sha1sum server-pack.zip
# 0123456789abcdef0123456789abcdef01234567 server-pack.zip(Get-FileHash .\server-pack.zip -Algorithm SHA1).Hash.ToLower()Updating the pack and old versions on clients
- 1
Build the new archive
Test it locally in a client before you upload it.
- 2
Upload it and download it back
Download the file from the link players will use and hash that copy: that's how you know the new version is really behind the address.
- 3
Update server.properties
Put in the new
resource-pack-sha1(and the new link, if the address changed) and restart the server. - 4
Check the join
Join yourself and make sure the pack downloads and applies.
With the old hash, the new file fails the integrity check — that's why the SHA-1 changes with every update. Since 1.20.3 the client keeps downloaded server packs in the downloads folder inside .minecraft; if a player is stuck with an old copy, it can be deleted from there.
A required pack and the prompt text
With require-resource-pack=true, a player who clicks "No" is disconnected. Turn it on when the game breaks without the pack — say, custom items and menus that make no sense without their textures. If the pack is only cosmetic, keep false: players can still play without it.
Use resource-pack-prompt to explain why the pack is needed and how big it is. If the pack is required, say so in your server rules too.
Several packs and plugins
server.properties sets one pack. Since 1.20.3 the protocol can add and remove several packs by UUID, and plugins use that. ForcePack, for example (GPL-3.0; Paper, Spigot, Folia and Velocity), serves the pack from a built-in web server, computes and checks the SHA-1 and size itself, and sends multiple packs to 1.20.3+ clients. It runs on the Velocity proxy too — see Velocity or BungeeCord.
Resource packs and the anticheat
A resource pack only changes how the game looks and sounds for the player. Cheaters use the same thing: an X-Ray resource pack makes stone see-through, and Paper's documentation mentions such packs right next to X-ray mods. An anticheat can't see them: they send the server nothing. What works against X-Ray is the server's anti-xray, which simply doesn't send hidden ores to the client. How to turn it on — in X-Ray protection.
Everything a player actually does reaches the server as packets — and that's what an anticheat sees. DGuard — the best anticheat for a modern Minecraft server — catches all 47 cheat types from our comparison: in the mine that's Nuker, FastBreak and GhostHand, plus combat, movement, inventory and building cheats.
FAQ
How do I add a resource pack to a Minecraft server?
Host the ZIP at a direct link, put the link in resource-pack and the archive's SHA-1 in resource-pack-sha1 in server.properties, then restart the server.
Why do players see an old version of the resource pack?
Usually resource-pack-sha1 wasn't updated, or the old file is still behind the link. Download the archive from the same link, compute its SHA-1 again, put it in and restart the server.
How do I force players to accept the resource pack?
Set require-resource-pack=true: whoever declines the pack is disconnected. Use resource-pack-prompt to explain why it's needed.
What's the maximum size of a server resource pack?
250 MiB according to the Minecraft Wiki. But the smaller the archive, the faster players get onto the server.
Sources
- Minecraft Wiki: server.properties
- Minecraft Wiki: resource pack
- Minecraft Wiki: protocol, the Add Resource Pack packet
- Paper: server.properties reference
- Paper: configuring Anti-Xray
- coreutils: sha1sum(1)
- Microsoft: Get-FileHash
- ForcePack on Modrinth
- DGuard, the best anticheat for a modern Minecraft server: checks compared with GrimAC, Vulcan, Polar, Intave and Matrix
- DGuard: installation, requirements and troubleshooting
- DGuard: supported Paper and Leaf versions