Resource-Pack fuer Minecraft-Server hosten: kompletter Leitfaden (2026)

Resource-Pack fuer Minecraft-Server hosten: kompletter Leitfaden (2026)

Wenn dein Server Custom-Models ueber ItemsAdder oirektive Oraxen ausspielt, einen eigenen Font benutzt, vier Sprachen mitliefert oder einfach ein Vanilla-Pack mit Lore-Texturen mitschickt, stehst du frueher oder spaeter vor derselben Frage: wo soll dieses Zip liegen, damit der Client es schnell und ohne Failed to download resource pack zieht. Dieser Leitfaden erklaert, wie du ein Pack korrekt hostest, wie du den sha1 erzeugst, welche server.properties-Schluessel auf 1.21+ gueltig sind, und warum Discord CDN seit Ende 2024 aus dem Spiel ist.

Warum das Pack selbst hosten und nicht ueber ein Plugin

Minecraft 1.20.3+ kann einem Client bis zu fuenfzig Resource-Packs ueber die Server-API schicken, aber das Texturpaket selbst reist nie ueber die Minecraft-Verbindung. Der Vanilla-Client oeffnet einen einfachen HTTPS-GET zur URL aus resource-pack= (oder zum URL des Plugins) und zieht das Zip direkt. Der Minecraft-Server ist an diesem Austausch nicht beteiligt: ihm ist egal, ob das Pack neben der Jar liegt oder auf einem anderen Kontinent, Hauptsache die URL antwortet und der Hash stimmt.

Daraus folgt eine einfache Regel: Pack-Geschwindigkeit und Stabilitaet haengen nicht an deinem Minecraft-Hosting, sondern daran, wo das Zip liegt. Wenn das Pack von einer billigen US-VPS mit 100 Mbps ausgeliefert wird, wartet ein Spieler aus Polen auf einer normalen Hausleitung 30 Sekunden nur am Tau-Ziehen, und jeder TCP-Hickser endet im Timeout. Liegt das Pack hinter einem ordentlichen CDN (Cloudflare, Bunny, R2), ist derselbe Download in 2-3 Sekunden durch, egal wo der Spieler sitzt.

Zweiter Punkt: force-resource-pack=true plus ein korrekter resource-pack-sha1 ist der Schluessel, damit der Client das Pack entweder automatisch akzeptiert oder sauber mit Failed to apply resource pack ablehnt. Ohne sha1 laedt der Client das Pack bei jedem Join neu; das ist verschenkter Traffic und verschenkte Sekunden auf der Spielerseite. Mit korrektem sha1 cached der Client das Archiv nach dem ersten Download und holt es spaeter einfach von der Platte.

Pack-Vorbereitung: pack.mcmeta, Format, Zippen

Bevor du irgendwas hostest, pruefe die Struktur. Layout fuer Minecraft 1.21+:

my-pack/
  pack.mcmeta
  pack.png
  assets/
    minecraft/
      textures/
      models/
      lang/
      sounds/

pack.mcmeta fuer 1.21.4 (Java Edition) traegt das pack_format. Jede Client-Version hat ihre eigene Nummer, die aktuelle Tabelle steht auf minecraft.wiki im Artikel Pack format. Stand Mitte 2025 ist 1.21.4 = pack_format 46 und 1.21 = 34. Falsche Nummer fuehrt nicht zu einer Fehlermeldung, der Client laedt einfach Teile der Texturen nicht.

{
  "pack": {
    "pack_format": 46,
    "supported_formats": [34, 46],
    "description": "MyServer textures 1.21+"
  },
  "language": {
    "de_de": {"name": "Deutsch", "region": "Germany", "bidirectional": false}
  }
}

supported_formats erlaubt Clients verschiedener Versionen, dasselbe Archiv zu akzeptieren, und language ist nur relevant, wenn du eine eigene lang/de_de.json ueber das Vanilla legst. Vergiss pack.png nicht (64x64 oder 128x128, normales PNG); der Client zeigt es in der Pack-Liste.

Archiv bauen. Wichtig: zippe den Inhalt, nicht den Ordner:

cd my-pack
zip -r -9 ../my-pack.zip . -x "*.DS_Store" -x ".*"

Pruefen: unzip -l my-pack.zip | head muss pack.mcmeta und assets/ direkt zeigen, ohne my-pack/-Wrapper. Mit Wrapper wirft der Client Couldn't load resource pack: invalid pack format.

sha1 erzeugen: sha1sum und Online-Tools

Minecraft prueft genau den SHA-1 ueber die Zip-Bytes, ohne Salz, ohne Tricks. Linux/macOS:

sha1sum my-pack.zip
8f3a9c1d4e2b6f7a8d9e0f1a2b3c4d5e6f708192  my-pack.zip

Windows via PowerShell:

Get-FileHash -Algorithm SHA1 .\my-pack.zip

Der Hash muss in server.properties lowercase stehen, sonst wirft der Vanilla-Client pack hash mismatch. Wenn du die Datei manuell editierst, kopiere die Ausgabe von sha1sum direkt. Wenn du Pack-Updates automatisierst, packe einen CI-Schritt drum:

HASH=$(sha1sum my-pack.zip | awk '{print $1}')
echo "resource-pack-sha1=${HASH}" > .env.pack

Das .env.pack wird beim Deploy in dein server.properties-Template gemerged.

Option 1: GitHub raw

Billigster und einfachster Weg, vor allem wenn das Pack ohnehin im Git liegt. Public Repo anlegen, my-pack.zip rein, raw-URL kopieren:

https://raw.githubusercontent.com/<user>/<repo>/main/my-pack.zip

Vorteile: kostenlos, Versionierung ueber Git-Tags und Commits, einfaches Rollback. Nachteile und Stolperfallen:

  • GitHub bewirbt raw nicht offiziell als Binary-CDN. Wenn dein Pack tausende Zugriffe pro Stunde bekommt, kannst du Rate-Limits sehen, im Extremfall wird der Account markiert.
  • Eine Datei in einem normalen Repo ist auf etwa 100 MB limitiert; groesseres Pack braucht Git LFS, und LFS hat seine eigene URL und Bandbreitenquote.
  • Latenz mittel. raw.githubusercontent.com laeuft ueber GitHub und Fastly, fuer die meisten Regionen ok, aber selten optimal.

Wann sinnvoll: kleiner Server, Pack unter 20 MB, weniger als 100-200 gleichzeitige Spieler.

Option 2: Mc-Packs.net

Ein dedizierter Host fuer Server-Resource-Packs. Zip ueber das Webformular auf mc-packs.net hochladen, direkte URL plus vorgerechneten sha1 erhalten. Sie haben eine API, um dieselbe URL bei einem Update zu rotieren.

Vorteile: kostenlos, keine eigene Infrastruktur, sha1 fertig zum Kopieren. Nachteile: du haengst an einem fremden Service, wenn deren Box hustet, laedt das Pack nicht mehr und du erfaehrst es aus dem Chat. Free-Tier ohne SLA, ohne Garantie, dass der Link in einem Jahr noch lebt.

Wann sinnvoll: Test-Server, kleines Produktivsystem, oder als Backup-Mirror zum Hauptserver.

Option 3: Cloudflare R2

R2 ist der S3-kompatible Objektspeicher von Cloudflare ohne Egress-Kosten (das ist der Hauptunterschied zu AWS S3). Speicher kostet Cents, Spieler-Downloads kosten nichts. Doku auf developers.cloudflare.com/r2.

Standardablauf:

  1. R2-Bucket anlegen.
  2. Zip via rclone oder aws s3 cp mit R2-Endpoint hochladen.
  3. Public Domain (packs.example.net) ueber die R2-Settings an den Bucket binden.
  4. Cache-Control: public, max-age=31536000, immutable auf das Zip setzen, damit Clients und der Cloudflare-Edge nicht mehr beim Origin nachfragen.

rclone-Upload:

rclone copy ./my-pack.zip r2:my-bucket/ --header-upload "Cache-Control: public,max-age=31536000,immutable"

URL fuer server.properties:

https://packs.example.net/my-pack-v12.zip

Beachte das -v12 im Dateinamen. Das ist Absicht: statt mit Cache-Invalidation zu kaempfen, bekommt jede neue Pack-Version einen neuen Namen, der sha1 aendert sich, alte Spieler ziehen den neuen File, der Cache funktioniert sauber. Auf R2 kostet das nichts, auf jedem anderen CDN ist es ebenfalls Best Practice.

R2-Vorteile: Cloudflare-Anycast, kein Egress-Billing, native Cloudflare-Cache-Integration, einfache Public Domain. Nachteile: einmaliges Setup mit Cloudflare-API und rclone, aber das machst du genau einmal.

Option 4: Self-hosted nginx oder Caddy

Wenn du ohnehin eine VPS oder einen dedizierten Server fuer die Server-Webseite betreibst, hoste statische Dateien dort. Minimal-nginx:

server {
    listen 443 ssl http2;
    server_name packs.example.net;

    ssl_certificate /etc/letsencrypt/live/packs.example.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/packs.example.net/privkey.pem;

    root /var/www/packs;

    location ~* \.zip$ {
        add_header Cache-Control "public, max-age=31536000, immutable";
        add_header Access-Control-Allow-Origin "*";
        sendfile on;
        tcp_nopush on;
    }
}

Caddy ist noch kuerzer:

packs.example.net {
    root * /var/www/packs
    file_server
    header /*.zip Cache-Control "public, max-age=31536000, immutable"
}

Vorteile: volle Kontrolle, fast keine Latenz wenn Pack-Host und Game-Host im selben DC stehen. Nachteile: du bist fuer Uptime, Backups und Bandbreite zustaendig. Mit 100 Mbps und 200 Spielern direkt nach einem Restart saettigt die Leitung 30 Sekunden lang und jemand timeoutet.

Sinnvoller Default: dein nginx hinter Cloudflare-Proxy (orange Wolke). Du bekommst kostenloses Edge-Caching und der Spike loest sich am Edge auf.

Discord CDN: warum NICHT

Jahrelang haben Admins das Zip in einen privaten Discord-Channel hochgeladen und die Attachment-URL in server.properties kopiert. Das funktionierte ewig, und bis Ende 2023 waren die URLs dauerhaft.

Ende 2023 hat Discord auf signierte temporaere URLs umgestellt (?ex=...&is=...&hm=...), und im Fruehjahr 2024 wurde das Standard fuer alle Attachments. Die Signatur laeuft nach etwa 24 Stunden ab. Setzt du heute so eine URL ein, sehen deine Spieler morgen Failed to download resource pack. Bot-Tricks, die die Signatur erneuern, retten dich auch nicht; die Discord-ToS verbieten ausdruecklich, ihren CDN als Hosting fuer Drittprojekte zu missbrauchen.

Fazit: Discord CDN ist fuer Resource-Packs gestorben. Wenn deine server.properties aktuell auf cdn.discordapp.com/... zeigt, wechsel zu einer der Optionen oben, bevor die Beschwerden kommen.

server.properties-Konfig

Auf Paper/Spigot/Folia 1.21+ gelten folgende Schluessel:

resource-pack=https://packs.example.net/my-pack-v12.zip
resource-pack-sha1=8f3a9c1d4e2b6f7a8d9e0f1a2b3c4d5e6f708192
require-resource-pack=true
resource-pack-prompt=Required textures for the server

Was du wissen solltest:

  • resource-pack-sha1 ist der korrekte Schluesselname, nicht resource-pack-hash, nicht sha-1. Dokumentiert auf minecraft.wiki unter Server.properties.
  • require-resource-pack=true ist das moderne Aequivalent zum alten force-resource-pack. Lehnt der Spieler ab, kickt der Server ihn mit der Nachricht aus resource-pack-prompt (oder einer Default-Nachricht, wenn prompt leer ist).
  • 1.20.3 und aelter hatten ein Limit von 224 Zeichen auf die URL. 1.20.3+ entfernte das Limit, aber bleib unter 1024 Zeichen; einige Launcher und Mods schneiden noch ab.
  • resource-pack-prompt akzeptiert eine simple JSON-Text-Component, du kannst Farben und Uebersetzungen einbauen.

Nach dem Editieren von server.properties musst du den Server neu starten; Hot-Reload dieser Schluessel funktioniert nicht.

Per-Player-Packs: ItemsAdder, Oraxen, force-resource-pack-Plugins

Ueber server.properties kannst du genau ein Pack ausspielen. Ab 1.20.3 kann die Server-API bis zu fuenfzig Packs pro Sitzung pushen, und jedes grosse Custom-Item-Plugin nutzt das.

ItemsAdder und Oraxen hosten das Pack selbst: Plugin installieren, es generiert das Zip, startet einen eingebetteten HTTP-Server (oder uebergibt an deinen nginx) und pusht es ueber ProtocolLib oder die Paper-API. Deine einzige Aufgabe: sicherstellen, dass der Listening-Port aus dem Internet erreichbar ist, nicht nur aus dem LAN.

Wenn du dein eigenes Pack obendrauf legen willst, gibt es Plugins der Sorte ResourcePackHost oder ForceResourcePack, die per PlayerJoinEvent ueber Player#setResourcePack(url, sha1) ein Pack pushen. Sie bieten meistens auch per-permission oder per-world Packs: ein Lobby-Pack im Hub, ein Survival-Pack im Spielserver.

Sonderfall: BungeeCord/Velocity. Auf dem Proxy gibt es kein server.properties, das Pack laeuft entweder ueber die Velocity-API oder ueber ein Plugin auf dem Backend. Die meisten Setups gehen den zweiten Weg, weil das einen Kontrollpunkt pro Server gibt.

Mehrsprachige Packs

Wenn dein Server ru/en/de uebersetzt, hast du zwei Wege: ein grosses Pack mit lang/-Ordnern fuer alle Sprachen (der Client waehlt selbst nach seinen Settings), oder mehrere Packs und pro Spieler verteilen ueber ein Plugin und Locale.

Der Vanilla-Weg ist sauberer: assets/minecraft/lang/ru_ru.json, en_us.json, de_de.json in ein Zip, im pack.mcmeta unter language listen. Das Archiv waechst kaum (Lang-Dateien sind 50-200 KB JSON), und alles laeuft ohne Plugin.

Wenn die Packs stark divergieren (Halloween-Texturen nur fuer ru-Clients), dann via Plugin pro Locale routen mit Player#getLocale().

Hosting-Optionen Tabelle

MethodeKostenGeschwindigkeitLimitsWann nehmen
GitHub rawkostenlosmittel100 MB Datei, soft Rate-Limitkleiner Server, <20 MB Pack
Mc-Packs.netkostenlosmittelkein SLA, fremde InfraTest, Mirror, kleine Prod
Cloudflare R2Cents/Monathoch (Anycast)Egress frei, Bucket-Groesse egalmittlere/grosse Prod
Nginx/CaddyVPS-Kostenje nach Uplinkdeine Uptime, deine Backupsbereits VPS vorhanden
Klassisches S3$$$ EgresshochEgress killt das Budgetbereits auf AWS
Discord CDNkostenloskurzURL stirbt nach 24 hnie

Debugging: Pack laedt nicht

Symptome und wo du graben musst:

  1. Failed to download resource pack. URL per Hand mit curl -I pruefen. Bei 200 OK und sinnvollem Content-Type (application/zip oder application/octet-stream), weiter im Text. 403 heisst das CDN blockiert dich, Regeln pruefen. Timeout heisst die URL ist von einer fremden Box nicht erreichbar; DNS oder Firewall fixen.

  2. Pack hash mismatch. In 99% der Faelle ist es ein sha1-Mismatch zwischen server.properties und tatsaechlicher Datei. Mit sha1sum neu berechnen, Wert exakt einfuegen, Server neu starten.

  3. Spieler sagen, das Pack laedt, aber Texturen werden nicht angewendet. pack_format in pack.mcmeta pruefen, vermutlich passt es nicht zur Client-Version. Ein supported_formats-Array hinzufuegen.

  4. Couldn't load resource pack: invalid pack format. Im Zip steckt ein Wrapper-Ordner. Per cd my-pack && zip -r ../my-pack.zip . neu packen, nicht zip -r my-pack.zip my-pack/.

  5. Custom CA. Liegt das Pack hinter selbstsigniertem TLS, lehnt der Vanilla-Client ab. Let's Encrypt, ZeroSSL oder ein anderes oeffentliches CA nehmen.

Versionierung ohne Schmerzen

Der haeufigste Pack-Update-Bug: du hast das Zip an derselben URL ersetzt, den sha1 im Config aktualisiert, den Server neu gestartet, aber ein Teil der Spieler laedt aus dem Cache noch das alte Pack. Der Cache ist auf URL gekeyed, nicht auf Inhalt.

Loesung: jede neue Pack-Version bekommt einen neuen Dateinamen. Statt pack.zip, ship pack-v1.zip, pack-v2.zip. Keine Cache-Invalidation, kein Cache-Control: no-cache, neue Spieler ziehen den aktuellen Build. Alte Dateien kannst du ein bis zwei Wochen spaeter loeschen, wenn alle nachgezogen haben.

Derselbe Trick loest auch das Problem mit langen CDN-Caches: Cloudflare- oder Bunny-Edges koennen Tage halten, du hast aber vor fuenf Minuten neu hochgeladen. Versionierte Dateinamen umgehen das komplett.

FAQ

Kann ich das Pack ueber HTTP ohne TLS ausliefern? Technisch ja, der Vanilla-Client akzeptiert http://. In der Praxis nicht: einige Firmennetze und Provider filtern unbekannte HTTP-Hosts, und Let's Encrypt ist kostenlos und mit zwei Befehlen installiert.

Was bei einem 200 MB Pack? Der Client akzeptiert es, aber ueberlege ein Splitting in Base + Addon und die zweite Stufe ueber die ItemsAdder/Oraxen-API. Grosse Zips bedeuten lange Downloads auf Mobilfunk und mehr Chancen auf Verbindungsabbrueche.

Warum immutable im Cache-Control? Es sagt Browser/Client, dass diese URL sich nie aendert. Mit versioniertem Dateinamen (pack-v12.zip) stimmt das, und der Client laesst Revalidation-Requests weg.

SHA-1 ist gebrochen, kann ich SHA-256 nehmen? Ja, ab Minecraft 1.20.3+ ueber die Server-API mit Player#setResourcePack und Hash-Parameter, aber das Feld in server.properties heisst weiter resource-pack-sha1. Krypto-Staerke ist hier irrelevant, der Hash ist nur Integritaetscheck und Cache-Key.

Was ist mit Bedrock-Packs? Bedrock funktioniert anders: das Pack reist ueber das Minecraft-Protokoll selbst, ohne HTTP. Bei Crossplay via Geyser/Floodgate liegen Custom-Bedrock-Packs separat im behavior_packs- und resource_packs-Ordner der Welt.

Kann ich das Pack vom Minecraft-Server selbst ausliefern? Technisch ja, Paper-Plugins koennen einen kleinen Web-Server hochziehen. In der Praxis nicht: Pack-Traffic kaempft mit Spieler-Traffic auf derselben Leitung, und die Tickrate leidet unter Last. Pack auf einen separaten Host oder CDN.

Sobald das Pack von einem CDN mit korrektem sha1, versionierten Dateinamen und vernuenftigem Cache-Control ausgeliefert wird, ist die Download-Geschichte kein Thema mehr. Spieler kriegen die Texturen in ein paar Sekunden, der Cache laeuft transparent, und beim Update laedst du einfach eine neue Datei mit neuem Namen hoch und uebernimmst den frischen Hash in den Config.


Schützen Sie Ihren Server vor DDoS-Angriffen

Kostenloser Schutz mit 5-Minuten-Einrichtung. 1 TB Traffic inklusive.

Kostenlos testen


Weitere Artikel