Jak czytać crash report serwera Minecraft: krok po kroku (2026)
Serwer właśnie padł, w konsoli czerwona ściana tekstu, a w crash-reports/ świeży plik na 800 linii. Jeśli zdarza się to raz w tygodniu i za każdym razem zgadujesz, który plugin jest winny, ten poradnik jest dla ciebie. Rozkładamy na czynniki strukturę crash reportu, czytamy stack trace oczami admina Paper 1.21, odróżniamy Java-side crash od natywnego JVM crash i wskazujemy winny plugin w sekundach.
Napisane pod Paper i Folia 1.21+ na Java 21, ale 90% dotyczy też Spigot, Purpur, Fabric i Forge. Wszystkie nazwy klas i exceptionów są prawdziwe, nic nie wymyślone.
Gdzie serwer zostawia crash report
Gdy Minecraft łapie fatal exception w głównym wątku tick, vanilla sam dumpuje raport. Trzy lokalizacje są ważne i wszystkie trzy trzeba sprawdzić:
crash-reports/crash-YYYY-MM-DD_HH.MM.SS-server.txtobokserver.jar. To główny artefakt, generowany przeznet.minecraft.CrashReportzaraz przed śmiercią procesu.hs_err_pid<PID>.logw katalogu roboczym serwera. Plik pochodzi od samej JVM HotSpot, pisany przez natywny kod runtime, gdy crash NIE jest w twoim kodzie Java tylko w samej VM: SIGSEGV, brak natywnej pamięci, bug JIT.logs/latest.logi zrolowanelogs/*.log.gz. Stack trace zwykle dubluje się tutaj plus kontekst minuty przed awarią. Bez latest.log crash report jest często bezużyteczny, bo nie widać, co plugin robił sekundę przed padem.
Paper czasem dorzuca czwarty plik: debug/ z dumpem TPS i wątków, jeśli watchdog zdążył wystartować. Na Paper 1.21.4+ sprawdź też ten katalog.
Najpierw: skopiuj plik w całości. Nie edytuj go, nie wycinaj "szumu". Pełny crash report to dokładnie to, czego potrzebuje autor pluginu, a w szumie często ukrywa się przyczyna.
Anatomia crash-XXXX.txt
Plik wygląda strasznie, ale układ ma mechaniczny. Typowy crash:
---- Minecraft Crash Report ----
// Don't be sad, have a hug! <3
Time: 2026-04-15 18:42:11
Description: Exception ticking world
java.lang.NullPointerException: Cannot invoke "org.bukkit.entity.Player.getInventory()" because the return value of "org.bukkit.Bukkit.getPlayer(String)" is null
at com.example.shopgui.ShopGuiPlus.onPlayerJoin(ShopGuiPlus.java:142) ~[ShopGUIPlus-1.94.0.jar:?]
at sun.reflect.GeneratedMethodAccessor412.invoke(Unknown Source) ~[?:?]
at org.bukkit.plugin.EventExecutor.execute(EventExecutor.java:123) ~[paper-api-1.21.4.jar:?]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:177) ~[paper-1.21.4.jar:?]
at net.minecraft.server.players.PlayerList.placeNewPlayer(PlayerList.java:215) ~[paper-1.21.4.jar:?]
...
Warstwa po warstwie. Linia-marker ---- Minecraft Crash Report ---- istnieje, by narzędzia jak mcprofile rozpoznawały to jako crash report, a nie zwykły log. Potem śmieszny cytat, humor Mojanga z net.minecraft.CrashReport.getErrorComment od 2012.
Time i Description dają kontekst. Description to to, co main thread robił w momencie exceptiona. Najczęstsze wartości: Exception ticking world, Exception in server tick loop, Loading entities, Unexpected error, Watching Server. Jeśli opis brzmi Watching Server, dump powstał z watchdoga po freezu, a nie z samego exceptiona, i stack trace pokazuje NIE winnego, ale wątek, który zawisł.
Dalej idzie sama klasa exceptiona i stos wywołań. To kluczowa część i poświęcamy jej kolejną sekcję.
Czytanie stack trace: gdzie padło vs kto winny
Kolejność w stack trace: na górze najnowszy frame (gdzie poszedł throw), na dole najstarszy (zwykle Thread.run). Początkujący admini często obwiniają najwyższą linię i się mylą.
Reguła jest prosta. Idź z góry na dół i znajdź pierwszy frame, który NIE jest vanilla Minecraft, NIE jest Bukkit/Paper API i NIE jest standardową biblioteką Java. Pakiety:
net.minecraft.*,com.mojang.*to vanilla. Rzadko winowajca.org.bukkit.*,io.papermc.*,org.spigotmc.*to API serwera. Też rzadko winne.java.*,jdk.*,sun.*to JDK. Crash tutaj to OOM, problem JIT albo wciśniętenulldo API.- Wszystko inne to kod trzeci. To twój winowajca.
W przykładzie pierwsza obca linia to at com.example.shopgui.ShopGuiPlus.onPlayerJoin(ShopGuiPlus.java:142) ~[ShopGUIPlus-1.94.0.jar:?]. Pakiet com.example.shopgui, jar ShopGUIPlus-1.94.0.jar, winowajca w sekundę. Plik ShopGuiPlus.java linia 142.
Ogon w nawiasach kwadratowych ~[ShopGUIPlus-1.94.0.jar:?] Paper dodaje specjalnie dla wygody. Na Spigocie tego nie ma, trzeba ręcznie znajdować pakiet. com.example.shopgui w Google prowadzi do ShopGUIPlus w pięć sekund.
Jeśli stack trace NIE zawiera obcego kodu i wszystko leży w net.minecraft.*, to albo bug vanilli (rzadko), uszkodzenie świata lub skutki cudzego buga: plugin zniszczył entity wcześniej, vanilla crashuje minutę później przy sprzątaniu. W takim razie otwórz latest.log i szukaj WARN/ERROR w minucie przed crashem.
Najczęstsze exceptions: znaczenie i naprawa
Dziewięć na dziesięć crashy to jeden z sześciu exceptionów. Znajomość wzorca oszczędza godzinę debuga.
NullPointerException. Ktoś wywołał metodę na obiekcie null. Java 14+ pisze diagnostykę Cannot invoke "X.method()" because Y is null. Mówi DOKŁADNIE, co było null. Zwykle plugin nie sprawdził Bukkit.getPlayer() lub world.getBlockAt().getState() na null. Fix: zaktualizować plugin lub zgłosić autorowi z trace.
ConcurrentModificationException. Wątek A modyfikuje kolekcję, gdy wątek B po niej iteruje. Plaga pluginów dotykających świata z async-taska. Operacje na świecie, chunkach, entities lub inwentarzach MUSZĄ być na main thread przez Bukkit.getScheduler().runTask(plugin, ...). Jeśli winny pakiet zawiera Async, Tasks lub Sync, to prawie na pewno on.
OutOfMemoryError: Java heap space. Heap się skończył. To nie bug kodu, to memory leak albo za mały -Xmx. Przed OOM JVM prawie zawsze pisze hs_err_pid lub java_pid<PID>.hprof (jeśli włączone -XX:+HeapDumpOnOutOfMemoryError). Otwórz hprof w Eclipse MAT lub VisualVM i zobacz, która klasa trzyma najwięcej. Na 1.21 typowi winowajcy: Citizens (zawieszone NPC), wielkie rendery Dynmap, pluginy z cachującym HashMap<UUID, ...> bez cleanupu.
StackOverflowError. Nieskończona rekurencja. Najczęściej cykliczne PlaceholderAPI: placeholder A rozwija B, B rozwija A. Albo EventListener wystrzeliwuje event ponownie wchodzący w tego samego listenera. Stack trace pokazuje TE SAME linie setki razy, szukaj wzorca.
NoClassDefFoundError / ClassNotFoundException. Plugin odwołuje się do klasy spoza classpath. Najczęściej:
- Plugin zależy od ProtocolLib/Vault/PlaceholderAPI, a nie wrzuciłeś go do plugins/.
- Zaktualizowałeś Paper, plugin używa klasy Mojang-mapped, której już nie ma (np.
net.minecraft.server.v1_17_R1.*po 1.17 zniknął). - Konflikt wersji: dwa pluginy zaszyły różne wersje tej samej biblioteki, ClassLoader wziął nie tę.
IllegalStateException na Paper 1.21 zwykle oznacza "dotknąłeś świata poza main thread", "iterator nieważny" lub "plugin disabled". Komunikat jest zwykle wprost.
Tabela: exception, prawdopodobna przyczyna, pierwszy krok
| Exception | Prawdopodobna przyczyna | Pierwszy krok |
|---|---|---|
| NullPointerException | Plugin nie sprawdził null po API call | Znaleźć pierwszy obcy pakiet w trace, zaktualizować |
| ConcurrentModificationException | Async-kod modyfikuje świat/entity | Wyłączyć plugin z "Async" w nazwie i przetestować |
| OutOfMemoryError: Java heap space | Memory leak lub -Xmx zbyt mały | Sprawdzić -Xmx, otworzyć heap dump w MAT |
| StackOverflowError | Cykliczna rekurencja (często PAPI) | Szukać powtarzających się linii w trace |
| NoClassDefFoundError | Brak zależności lub konflikt wersji | Sprawdzić obecność wymaganych pluginów |
| IllegalStateException | Async dostęp do API lub disabled plugin | Przeczytać komunikat, zwykle wprost |
hs_err_pid: gdy crashuje sama JVM
Jeśli w katalogu serwera pojawi się hs_err_pid12345.log, to inna kategoria crasha. Java exceptions JVM łapie czysto. Gdy widzisz hs_err_pid, sama maszyna wirtualna padła: SIGSEGV, SIGBUS, brak natywnej pamięci, bug JIT.
Plik zaczyna się tak:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f4a8c1d3a40, pid=12345, tid=12378
#
# JRE version: OpenJDK Runtime Environment Temurin-21.0.4+7 (21.0.4+7) (build 21.0.4+7-LTS)
# Java VM: OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (21.0.4+7-LTS, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C [libc.so.6+0x9aa40]
#
Na co patrzeć:
Problematic frameto najważniejsza linia. Jeśli jestC [libc.so.6+...]lubC [libfreetype.so+...], to natywna biblioteka OS. Zwykle sterownik NIC, glibc na starym Ubuntu, OpenSSL.- Jeśli
Problematic frametoJ net.minecraft.server.MinecraftServer.tick, to bug JIT, podnieś Javę do najnowszego patcha. JRE versionma znaczenie. Java 17.0.2 miała znanego buga JIT, 21.0.0 GA też miała. Przejdź na najnowszego Temurina LTS, patrz adoptium.net.- Sekcja
THREADpokazuje, co robił wątek. Jeśli to"Server thread"lecący przezorg.bukkit.craftbukkit.v1_21_R3.*, serwer po prostu tickował i padł w natywie. - Sekcja
Memoryważna przy OOM. PatrzNative Memory Trackingjeśli JVM startowała z-XX:NativeMemoryTracking=summary.
Jeśli hs_err_pid pojawia się regularnie, sprawdź RAM przez memtest86 przez noc (na dedyku). Wadliwa kość daje SIGSEGV w losowych miejscach. Częściej niż chciałbyś.
Latest.log: kontekst minuty przed crashem
Crash report pokazuje sam moment awarii. Co działo się WCZEŚNIEJ siedzi w logs/latest.log. Otwórz i znajdź timestamp 30-60 sekund przed Time z crash reportu. Interesują cię:
[WARN]i[ERROR]od pluginów. Często plugin pięć minut pisze ostrzeżenia, potem pada.Can't keep up!i komunikaty watchdoga. Serwer freezeował przed śmiercią.- Loginy graczy. Jeśli crash zawsze przy login konkretnego UUID, zwykle ich
playerdata/<uuid>.datjest popsute. - Komendy admina lub pluginów. Operacje WorldEdit,
/reload(nigdy nie rób/reloadna live), masowe kicki.
Użyteczna kombo: latest.log dwie sekundy przed crashem pisze [WARN] [ShopGUIPlus] Failed to load shop config for player Steve, a stack crash reportu kończy się w ShopGuiPlus.onPlayerJoin. Winowajca potwierdzony bez zgadywania.
Szukanie winnego pluginu: od pakietu do downloadu
Trace pokazał at com.example.shopgui.ShopGuiPlus.onPlayerJoin. Co dalej:
- Otwórz
plugins/i znajdź jar po nazwie z nawiasówShopGUIPlus-1.94.0.jar. Zapamiętaj wersję. - Bez nawiasów (Spigot):
unzip -p plugins/*.jar plugin.yml | grep -A1 main:i dopasujmain:do pakietu. Output mówi, który jar zawiera pakiet. - Google na
com.example.shopguizwykle prowadzi do SpigotMC resources, Modrinth lub GitHuba autora. - Sprawdź wersję pluginu vs ostatnie wydanie. Każdy zasób SpigotMC ma changelog i issue tracker.
- Jeśli ostatnia wersja jest nowsza i changelog ma "fix NullPointerException on player join", podnoś. Załatwione.
- Jeśli już jesteś na ostatniej, otwórz issue. Załącz CAŁY crash report (przez pastebin, mclo.gs albo gist GitHub), wersję Paper (
/version), wersję Java (java -version) i kroki reprodukcji.
Dla pluginów Paperowych dobry zwyczaj: sprawdzić, czy taki crash nie jest już zgłoszony w Paper issues. Czasem winny jest sam Paper, zwłaszcza zaraz po nowym release.
Narzędzia, które przyspieszają triage
mclo.gs bierze crash report i wyróżnia pakiety pluginów osobnymi blokami. Wygodne do dzielenia w Discordowych kanałach supportu.
mcprofile.io parsuje crashe i koloruje stack frames wg właściciela. Brak płatnych funkcji, wszystko za darmo.
Dla dumpów hprof Eclipse MAT jest standardem od piętnastu lat. Otwiera dumpy do 8 GB na laptopie, patrz eclipse.dev/mat.
IntelliJ IDEA Community otwiera hs_err_pid i dzieli go na zakładki. Też za darmo.
Jeśli nie chcesz nic instalować lokalnie, zwykły grep pokrywa 80% przypadków: grep -A 30 "Stacktrace:" crash-reports/crash-*.txt daje sam stack bez szumu.
Jak zgłosić bug autorowi pluginu
Dobry issue to różnica między "zamknięty w dzień" i "ignorowany pół roku". Minimum:
- Wersja pluginu (
/version <Plugin>). - Wersja serwera (
/version, cała linia z numerem buildu Paper). - Wersja Java (
java -version). - Pełny crash report przez mclo.gs lub gist GitHub. Nigdy nie wklejaj 800 linii w treść issue.
- latest.log z pięciu minut przed crashem, też przez mclo.gs.
- Kroki reprodukcji. Jeśli crash losowy, napisz: "happens randomly 1-2 times per day, no obvious trigger".
- Lista pluginów lecących obok winowajcy.
Czego NIE robić: nie wklejać surowego tekstu, nie edytować crash reportu ("usunąłem szum"), nie pisać tylko "crashed pls fix".
FAQ
Co ważniejsze, crash-report.txt czy hs_err_pid?
Jeśli masz oba, zacznij od crash-report.txt. To Java exception z sensownym stack trace i identyfikowalnym pluginem. hs_err_pid czytasz, gdy crash-report.txt w ogóle nie powstał lub zawiera tylko opis Watching Server bez użytecznego trace.
Dlaczego trace pokazuje tylko net.minecraft.* i żadnego pluginu?
Dwa powody. Albo crash padł na wątku, który nie odpalał kodu pluginu (chunk gen, sieć), a plugin zepsuł dane wcześniej. Albo to dump watchdoga, więc stack pokazuje zamrożony main thread, nie przyczynę freezu. W obu przypadkach otwórz latest.log i szukaj WARN 30 sekund przed czasem crasha.
Serwer crashuje na starcie i nie powstaje crash report. Gdzie patrzeć?
Jeśli proces ginie przed utworzeniem crash-reports/, log idzie na stdout. Odpal serwer w screen/tmux lub z 2>&1 | tee start.log i sprawdź stdout. Zwykle to NoClassDefFoundError od pluginu z brakującą zależnością albo niekompatybilną Javą.
Jak odróżnić OOM od zwykłego laga?
OOM widać jako java.lang.OutOfMemoryError: Java heap space albo GC Overhead Limit Exceeded. Jeśli tego nie ma, ale TPS spadł do zera i watchdog ubił serwer minutę później, to NIE OOM tylko długi GC pause albo zawieszony plugin. Odpal Spark profiler (/spark profiler) i nagraj flame graph.
Co robić z serwerem padającym za każdym razem na innym crash report?
Klasyczny objaw problemu sprzętowego lub uszkodzonego świata. Najpierw memtest86 przez noc na dedyku. Potem sprawdź świat przez chunky albo regionfixer. Na zarządzanym hostingu poproś o przeniesienie na inny węzeł, czasem hałaśliwy sąsiad OOMuje twoją JVM.
Czy wyłączyć -XX:+HeapDumpOnOutOfMemoryError?
Nie, zostaw włączone. Dump powstaje raz przy OOM i jest mniej więcej rozmiaru -Xmx. Przy -Xmx16G to 16 GB, miej wolne miejsce na dysku. Bez heap dumpa znalezienie memory leaka jest możliwe, ale dużo dłuższe.
Jeśli twój serwer pada raz w tygodniu, a każdy crash report rymuje się z poprzednim, prawdopodobnie już wiesz, który plugin jest winny. Ale jeśli pady są losowe i nie ma czytelnego wzorca, sprawdź, czy nie wali w ciebie burza pakietów obciążająca stos sieciowy i zatykająca prawdziwym graczom logowanie. MineGuard zatrzymuje takie ataki zanim dojdą do Minecraft i zostawia w logach tylko prawdziwe crashe pluginów.
Chroń swój serwer przed atakami DDoS
Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.
Wypróbuj za darmoPowiązane artykuły
Jak działa ochrona DDoS: wyjaśniamy prostymi słowami
Krok po kroku rozkładamy, jak ochrona DDoS filtruje ruch, odróżnia graczy od botów i nie pozwala atakowi położyć twojego serwera. Przekierowanie DNS, scrubbing, tunele GRE, anycast i weryfikacja protokołu Minecraft.
Najlepsze pluginy bezpieczeństwa Minecraft 2026: uczciwy przegląd
Rozkładamy pluginy bezpieczeństwa dla serwerów Minecraft: autoryzacja, anticheat, ochrona przed botami, uprawnienia, logowanie. Uczciwe plusy i minusy każdego rozwiązania z radami konfiguracji.
SYN-flood: najczęstszy atak DDoS na serwery Minecraft
Rozkładamy mechanikę SYN-flooda: jak atakujący eksploatują TCP handshake, dlaczego serwery Minecraft są szczególnie podatne i jakie metody ochrony naprawdę działają. Konkretne komendy, configi sysctl i reguły iptables.