Как прочитать crash report Minecraft сервера: пошаговый гайд (2026)
Сервер только что упал, в консоли красная стена текста, а в crash-reports/ появился свежий файл на 800 строк. Если такое случается раз в неделю и каждый раз приходится гадать, какой плагин виноват, эта инструкция для вас. Разбираем структуру crash report, читаем stack trace глазами админа Paper 1.21, отличаем падение Java-кода от нативного JVM crash и быстро находим имя виноватого плагина.
Гайд написан под Paper и Folia 1.21+ на Java 21, но 90% применимо к Spigot, Purpur, Fabric и Forge. Все имена классов и исключений настоящие, без выдумок.
Где сервер кладёт crash report
Когда Minecraft ловит fatal exception в главном потоке тика, ванильный код сам делает дамп. Файлы лежат в трёх местах, и вам нужно проверить все три:
crash-reports/crash-YYYY-MM-DD_HH.MM.SS-server.txtрядом сserver.jar. Это основной артефакт, его генерируетnet.minecraft.CrashReportперед тем, как процесс умрёт.hs_err_pid<PID>.logв рабочей директории сервера. Это файл от самой JVM HotSpot, его пишет нативный код runtime, когда падает не Java-код, а сам интерпретатор: SIGSEGV, нехватка native-памяти, баг в JIT.logs/latest.logи сжатыеlogs/*.log.gz. Stack trace часто дублируется сюда же плюс контекст за минуту до краша. Без latest.log crash report часто бесполезен, потому что не видно, что делал плагин за секунду до падения.
В Paper иногда появляется четвёртый файл: debug/ с дампом TPS и потоков, если сервер успел запустить watchdog. Если у вас Paper 1.21.4+, проверьте этот каталог тоже.
Первым делом скопируйте файл целиком. НЕ редактируйте его, не вырезайте "шум". Полный crash report нужен автору плагина, и в шуме часто прячется первопричина.
Анатомия crash-XXXX.txt
Файл выглядит страшно, но устроен из понятных секций. Берём типичный 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:?]
...
Разберём по слоям. Первая строка-маркер ---- Minecraft Crash Report ---- нужна, чтобы инструменты вроде mcprofile понимали, что это именно crash report, а не латест-лог. Дальше идёт смешная цитата (этот юмор Mojang в коде с 2012 года, см. net.minecraft.CrashReport.getErrorComment).
Time и Description дают контекст. Description это то, что main thread пытался делать в момент исключения. Самые частые значения: Exception ticking world, Exception in server tick loop, Loading entities, Unexpected error, Watching Server. Если описание Watching Server, дамп сделал watchdog после фриза, а не само исключение, и stack trace покажет НЕ виновника, а тред, который завис.
После описания идёт собственно exception класс и стек вызовов. Это самая важная часть, и ей посвящён следующий раздел.
Чтение stack trace: где упало vs кто виноват
В stack trace порядок такой: сверху самый последний кадр (там, где конкретно бросили исключение), снизу самый первый (откуда всё началось, обычно Thread.run). Поэтому новички часто винят первую строку, и часто ошибаются.
Правило простое. Идите сверху вниз и ищите первый кадр, который НЕ принадлежит ванильному Minecraft, не Bukkit/Paper API и не Java standard library. Это пакеты:
net.minecraft.*,com.mojang.*это ваниль. Сами по себе крашатся редко.org.bukkit.*,io.papermc.*,org.spigotmc.*это API сервера. Тоже редко виноваты.java.*,jdk.*,sun.*это JDK. Если падает тут, это либо OOM, либо ошибка JIT, либо вы скормили APInull.- Всё остальное чужой код. Это ваш виновник.
В примере выше первая "чужая" строка это at com.example.shopgui.ShopGuiPlus.onPlayerJoin(ShopGuiPlus.java:142) ~[ShopGUIPlus-1.94.0.jar:?]. Пакет com.example.shopgui, jar ShopGUIPlus-1.94.0.jar, виновник найден за секунду. Файл ShopGuiPlus.java строка 142.
Хвост в квадратных скобках ~[ShopGUIPlus-1.94.0.jar:?] Paper добавляет специально для удобства. На Spigot его не бывает, там придётся искать пакет вручную: com.example.shopgui гуглится как ShopGUIPlus за 5 секунд.
Если в stack trace ВООБЩЕ нет чужого кода и всё в net.minecraft.*, это либо баг ванили (редко), либо повреждение мира, либо последствия чужого бага: левый плагин уронил entity ранее, а ваниль крашнулась через минуту, разгребая последствия. В таком случае откройте latest.log и ищите WARN/ERROR за минуту до crash report.
Common exceptions: что значат и как чинить
Девять из десяти крашей это одно из шести исключений. Знание паттерна экономит час дебага.
NullPointerException. Кто-то обратился к объекту, который null. С Java 14+ JVM пишет диагностику: Cannot invoke "X.method()" because Y is null. Это говорит, ЧТО именно null. Чаще всего плагин не проверил Bukkit.getPlayer() или world.getBlockAt().getState() на null. Фикс: обновить плагин или сообщить автору с trace.
ConcurrentModificationException. Поток модифицирует коллекцию, по которой кто-то итерируется. Это бич плагинов, которые трогают мир из async-задачи. Любые операции с миром, чанками, entity, инвентарями ОБЯЗАНЫ выполняться в main thread через Bukkit.getScheduler().runTask(plugin, ...). Если падает плагин с пакетом, в названии которого есть Async, Tasks или Sync, это почти наверняка он.
OutOfMemoryError: Java heap space. Куча кончилась. Это не баг кода, это утечка памяти или просто маленький -Xmx. Перед OOM JVM почти всегда успевает написать hs_err_pid или java_pid<PID>.hprof (если включён -XX:+HeapDumpOnOutOfMemoryError). Откройте hprof в Eclipse MAT или VisualVM и смотрите, какой класс держит больше всего памяти. На 1.21 типичные виновники: Citizens (зависшие NPC), большие Dynmap-рендеры, плагины с кеширующими HashMap<UUID, ...> без cleanup.
StackOverflowError. Бесконечная рекурсия. Чаще всего это циклический PlaceholderAPI: placeholder A раскрывает B, B раскрывает A. Или EventListener бросает событие, которое снова вызывает того же листенера. Stack trace будет показывать ОДНИ И ТЕ ЖЕ строки сотни раз, ищите паттерн.
NoClassDefFoundError / ClassNotFoundException. Плагин ссылается на класс, которого нет в classpath. Чаще всего это произошло потому, что:
- Плагин зависит от ProtocolLib/Vault/PlaceholderAPI, а его не положили в plugins/.
- Вы обновили Paper до новой версии, и плагин пытается дёргать Mojang-mapped класс, которого больше нет (например,
net.minecraft.server.v1_17_R1.*после 1.17 переименовали). - Конфликт версий: два плагина принесли разные версии одной библиотеки, и ClassLoader дал не тот.
IllegalStateException в Paper 1.21 чаще всего значит "вы трогаете world не из main thread", "итератор не валиден" или "plugin disabled". Текст исключения почти всегда говорит проблему явно.
Таблица: исключение, причина, первый шаг
| Исключение | Вероятная причина | Первый шаг |
|---|---|---|
| NullPointerException | Плагин не проверил null после API call | Найти первый чужой пакет в trace, обновить плагин |
| ConcurrentModificationException | Async код трогает мир/entity | Отключить плагин с "Async" в имени, проверить |
| OutOfMemoryError: Java heap space | Утечка памяти или маленький -Xmx | Проверить -Xmx, снять heap dump, открыть в MAT |
| StackOverflowError | Циклическая рекурсия (часто PAPI) | Искать повторяющиеся строки в trace |
| NoClassDefFoundError | Нет зависимости или конфликт версий | Проверить плагины-зависимости в plugins/ |
| IllegalStateException | Async доступ к API или disabled plugin | Прочитать message, обычно явный |
hs_err_pid: когда падает сама JVM
Если в каталоге сервера появился hs_err_pid12345.log, это другая категория крашей. Java-исключение JVM ловит штатно. Когда вы видите hs_err_pid, упала сама виртуальная машина: SIGSEGV, SIGBUS, нехватка native-памяти, баг JIT-компилятора.
Файл начинается так:
#
# 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]
#
Что смотреть:
Problematic frameэто самое важное. Если тамC [libc.so.6+...]илиC [libfreetype.so+...], это нативная библиотека OS. Часто это драйвер NIC, glibc на старой Ubuntu, OpenSSL.- Если
Problematic frameэтоJ net.minecraft.server.MinecraftServer.tick, это баг JIT, обновите Java на свежий патч-релиз. JRE versionважен. На Java 17.0.2 был известный JIT-баг, на 21.0.0 GA тоже. Поднимите Java до последней Temurin LTS, см. adoptium.net.- Раздел
THREADпоказывает, что делал поток. Если это"Server thread"и стек идёт черезorg.bukkit.craftbukkit.v1_21_R3.*, значит сервер просто тикал и упал в нативе. - Раздел
Memoryважен при OOM. СмотритеNative Memory Trackingесли запускали JVM с-XX:NativeMemoryTracking=summary.
Если hs_err_pid появляется регулярно, проверьте RAM сервера через memtest86 (на dedicated). Битая планка памяти кладёт JVM в SIGSEGV в случайных местах. Это чаще, чем хочется.
Latest.log: контекст за минуту до краша
Crash report показывает сам момент падения. Что было ДО, видно в logs/latest.log. Откройте его и найдите timestamp за 30-60 секунд до Time из crash report. Вас интересуют:
[WARN]и[ERROR]от плагинов. Часто плагин 5 минут писал предупреждения, потом упал.Can't keep up!и сообщения watchdog. Сервер фризил перед смертью.- Логи входа игроков. Если краш всегда происходит при login конкретного UUID, скорее всего поломан их
playerdata/<uuid>.dat. - Команды от админа или плагинов.
WorldEditoperation,/reload(никогда не делайте/reloadна проде), массовый kick.
Пример полезной комбинации: latest.log за 2 секунды до краша пишет [WARN] [ShopGUIPlus] Failed to load shop config for player Steve, а в crash report стек упал в ShopGuiPlus.onPlayerJoin. Виновник найден без догадок.
Поиск виновного плагина: от пакета к скачиванию
Итак, в trace вы нашли at com.example.shopgui.ShopGuiPlus.onPlayerJoin. Что дальше:
- Откройте
plugins/и найдите jar по имени из квадратных скобок:ShopGUIPlus-1.94.0.jar. Запомните версию. - Если квадратных скобок нет (Spigot), запустите
unzip -p plugins/*.jar plugin.yml | grep -A1 main:и сопоставьте main-класс с пакетом. Команда покажет, какой jar содержит указанный пакет. - Гугл по
com.example.shopguiобычно ведёт на SpigotMC resources, Modrinth или GitHub автора. - Проверьте версию плагина против последней. На SpigotMC у каждого ресурса есть changelog и issue tracker.
- Если последняя версия плагина новее вашей и в её changelog есть строка "fix NullPointerException on player join", обновите. Решено.
- Если ваша версия уже последняя, заводите issue. Включите ВЕСЬ crash report (через pastebin, mclo.gs или GitHub gist), версию Paper (
/version), версию Java (java -version) и шаги воспроизведения.
Для Paper плагинов хорошая практика: проверить, не дублируется ли краш в issues PaperMC. Иногда виноват не плагин, а сам Paper, особенно сразу после релиза новой версии.
Инструменты, которые ускоряют разбор
mclo.gs загружает crash report и автоматически выделяет пакеты плагинов в отдельные блоки. Удобно для шаринга в Discord-канале поддержки плагина.
mcprofile.io парсит crash и подсвечивает stack frames цветом по принадлежности. Платных фич нет, всё бесплатно.
Для hprof-дампов Eclipse MAT остаётся стандартом 15 лет. Открывает дампы до 8 GB на ноуте без проблем, см. eclipse.dev/mat.
IntelliJ IDEA Community может открыть hs_err_pid и распарсить его на табы. Тоже бесплатно.
Если вам не хочется ставить ничего локально, ванильный grep в bash покрывает 80% задач: grep -A 30 "Stacktrace:" crash-reports/crash-*.txt сразу даст stack без шума.
Как репортить баг автору плагина
Хороший issue это разница между "автор закроет за день" и "автор проигнорирует на полгода". Минимальный набор:
- Версия плагина (
/version <Plugin>). - Версия сервера (
/version, копируйте полностью включая build number Paper). - Версия Java (
java -version). - Полный crash report через mclo.gs или GitHub gist. Никогда не вставляйте 800 строк прямо в issue.
- latest.log за 5 минут до краша, тоже через mclo.gs.
- Шаги воспроизведения. Если краш случайный, так и пишите: "happens randomly 1-2 times per day, no obvious trigger".
- Список конфликтующих плагинов: что стоит вместе с виновником.
Чего НЕ делать: не вставлять текстом, не редактировать crash report ("я убрал лишнее"), не писать только "crashed pls fix".
FAQ
Что важнее, crash-report.txt или hs_err_pid?
Если есть оба, начинайте с crash-report.txt: это Java-исключение, у него есть осмысленный stack trace и плагин-виновник. hs_err_pid читают, когда crash-report.txt не появился вовсе или содержит только описание Watching Server без полезного trace.
Почему в trace одни net.minecraft.*, а виновный плагин не виден?
Два варианта. Либо краш произошёл в потоке, который не запускал плагин (chunk gen, network), и плагин уронил данные раньше. Либо это watchdog dump, и stack показывает зависший main thread, а не источник зависания. В обоих случаях откройте latest.log и ищите WARN за 30 секунд до Time crash report.
Сервер крашится сразу при старте, crash report не пишется. Что смотреть?
Если процесс умирает до того, как успел создать crash-reports/, лог уйдёт в стандартный вывод. Запустите сервер в screen/tmux или с 2>&1 | tee start.log и посмотрите stdout. Часто это NoClassDefFoundError от плагина с битой зависимостью или несовместимой версией Java.
Как отличить OOM от обычной лагалки?
OOM в логах выглядит как java.lang.OutOfMemoryError: Java heap space либо как GC Overhead Limit Exceeded. Если этого нет, но TPS упал в ноль и через минуту watchdog убил сервер, это НЕ OOM, это длинный GC-pause или зависший плагин. Запустите Spark profiler (/spark profiler) и снимайте flame-graph.
Что делать с repeatedly падающим сервером, если crash report каждый раз разный?
Это классический симптом железной проблемы или повреждённого мира. Сначала прогоните memtest86 ночью на dedicated. Затем проверьте world через chunky или regionfixer. На third-party хостингах попросите перенести вас на другую ноду, иногда у соседа OOM выкидывает вашу JVM.
Стоит ли отключать -XX:+HeapDumpOnOutOfMemoryError?
Нет, оставляйте включённым. Дамп пишется один раз при OOM и весит как ваш -Xmx. На сервере с -Xmx16G это 16 GB, проверьте, что свободного места на диске хватает. Без heap dump найти утечку памяти можно, но в разы дольше.
Если сервер падает раз в неделю и каждый crash report похож на предыдущий, скорее всего вы уже знаете, какой плагин виноват. Но если падения случайные и читаемого паттерна нет, проверьте, не приходит ли извне пакетный шторм, который роняет сетевой стек, и не мешает ли DDoS-атака игрокам коннектиться. MineGuard ловит такие атаки до того, как они доходят до Minecraft, и оставляет в логах только реальные краши плагинов.
Protege tu servidor contra ataques DDoS
Protección gratuita con configuración en 5 minutos. 1 TB de tráfico incluido.
Probar gratisArtículos relacionados
XDP и eBPF: фильтрация пакетов нового поколения для игровых серверов
Как XDP и eBPF позволяют фильтровать пакеты на уровне драйвера сетевой карты, обрабатывая 14+ миллионов пакетов в секунду на одном ядре. Почему iptables слишком медленный для современных DDoS-атак и как программируемая фильтрация меняет защиту игровых серверов.
Must-have плагины для Minecraft сервера в 2026 году
Подборка лучших плагинов для Minecraft сервера в 2026 году: безопасность, производительность, администрирование, экономика и мониторинг. Разбираем каждую категорию с конкретными рекомендациями.
Обнаружение VPN и прокси на Minecraft сервере: зачем и как
Полное руководство по обнаружению VPN и прокси-соединений на Minecraft сервере. Методы детектирования, API-сервисы, плагины, проблема ложных срабатываний и баланс между безопасностью и доступностью.