RE:NODE

Valheim mod conflicts: dependencies, patches and bisecting

By RE:NODE Team
13 min read


When a modded Valheim server stops working after you add or update something, the cause is nearly always one of four things: a dependency that is missing or too old, two mods patching the same piece of game code in incompatible ways, two mods trying to do the same job, or a client and server running different versions. The first and last announce themselves in the log. The middle two are quieter, and the only reliable way to find them is to split the mod set in half and test until one mod is left. This guide covers how to tell the four apart, what BepInEx writes when each one happens, and how to bisect a set of forty mods in six restarts instead of forty.

The four kinds of conflict#

It helps to name the problem before hunting for it, because each kind has a different tell and a different fix.

KindTypical symptomWhere it showsFix
Missing or old dependencyA mod simply does not loadLogOutput.log at start-upInstall or update the library
Clashing patchesErrors when a feature is used, odd behaviourExceptions in the log during playRemove one mod, or find a compatibility patch
Two mods, one jobDoubled effects, broken UI, desyncOften nothing in the logKeep one of the two
Version mismatchKicked on joinConnection message, server logMatch client and server sets

The fourth is not really a conflict between mods, it is a conflict between machines, and it has its own guide: kicked for mod version mismatch walks through the Jotunn and ServerSync messages in detail. This post concentrates on the first three, which happen on a single machine and break the server or the game no matter who connects.

A useful first question is whether the problem is on the server, on the clients, or both. If the server console shows errors before anyone connects, it is the server's mod set. If the server starts cleanly and one player's game misbehaves, it is that player's set. If every player sees the same broken feature, it is usually a mod installed on both sides, and you can debug it on whichever machine is easier to restart - normally a client.

Dependency chains and what BepInEx says about them#

Very few Valheim mods stand alone. Content mods lean on Jotunn, the shared modding library; many popular mods bundle ServerSync for pushing config to clients; Jotunn itself needs HookGenPatcher. A mod's Thunderstore package declares these in its manifest.json as dependency strings of the form Author-Name-Version:

manifest.json
{  "name": "ExampleMod",  "version_number": "1.4.0",  "dependencies": [    "denikson-BepInExPack_Valheim-5.4.2202",    "ValheimModding-Jotunn-2.20.0"  ]}

The version in that string is the version the author built against, not a strict pin. r2modman and the other mod managers read it and install the dependency for you, usually at its latest version. A manual install does not: if you copy a single .dll into BepInEx/plugins without its library, BepInEx refuses to load it. On a server that is the most common way to end up with a mod that works for every player and silently does nothing on the server, because the server was set up by hand and the clients through a manager. Thunderstore and r2modman for groups covers keeping the two in step.

Inside the .dll, a plugin declares the same relationships to BepInEx with attributes, and BepInEx's chain loader enforces them at start-up:

  • A hard dependency means "do not load me without this". If it is missing, the mod is skipped.
  • A soft dependency means "if this is present, load it first". Nothing breaks if it is absent; the mod just loses whatever integration it had.
  • An incompatibility means "do not load me if this is present". Authors add it when they know two mods cannot coexist.
  • A minimum version on a hard dependency means the library must be at least that version, so an old Jotunn fails the check even though it is installed.

Each of these produces a specific line in the log. With BepInEx 5, which is what the Valheim pack ships, they look like this (names here are examples):

BepInEx/LogOutput.log
[Info   :   BepInEx] Loading [Jotunn 2.20.0][Error  :   BepInEx] Could not load [ExampleMod 1.4.0] because it has missing dependencies: com.jotunn.jotunn (v2.21.0 or newer)[Error  :   BepInEx] Could not load [OtherMod 2.0.1] because it is incompatible with: some.other.mod[Warning:   BepInEx] Skipping [ExampleMod 1.3.0] because a newer version exists (ExampleMod 1.4.0)

The dependency is named by its plugin GUID, not its Thunderstore name, which is why com.jotunn.jotunn appears rather than ValheimModding-Jotunn. The GUID is usually guessable; if it is not, search the mod's Thunderstore page or README for it. The "Skipping" line means two copies of the same mod are installed, typically one in plugins and one in a subfolder left over from an earlier manual install. BepInEx loads the newer one, which is fine until you delete the newer one and the stale copy springs back to life. Remove duplicates whenever you see that line.

Clashing patches#

Almost every Valheim mod works by patching the game's own methods at runtime with Harmony (BepInEx ships the HarmonyX fork). A patch can run code before a game method (a prefix), after it (a postfix), or rewrite the method's instructions directly (a transpiler). Many mods can patch the same method and usually they coexist, because each postfix just adds a little behaviour on top. The trouble starts in three situations:

  1. A prefix that skips the original. A prefix can tell Harmony not to run the game's method at all. If mod A does that to replace a crafting check and mod B's postfix assumed the original ran, mod B now acts on values that were never set.
  2. Two transpilers on one method. A transpiler looks for a particular sequence of instructions and rewrites it. If another transpiler already rewrote that sequence, the second one cannot find what it was looking for and either fails to apply or applies in the wrong place.
  3. A patch against code that changed. After a game update, a method may be renamed, removed or rewritten. Patches against it fail, and every mod that relied on that patch loses that feature.

Patch failures that happen at start-up are logged by HarmonyX with the method that could not be patched and a stack trace. Patch problems that happen during play show up as exceptions whose stack trace includes the mod's namespace - a NullReferenceException thrown inside SomeAuthor.SomeMod.Patches.InventoryGui_Patch tells you which mod was running when it went wrong, even if it is not the mod at fault. Read the whole trace: the mod at the top is the one that crashed, but a frame further down from a different mod is often the one that changed the state it tripped over.

There is no built-in report of which mods patch which method. In practice you find these clashes by noticing that the broken feature belongs to an area two of your mods both touch - inventory, crafting, building placement, the map - and testing with one of them removed.

Two mods doing the same job#

The quietest conflict is two mods that each work perfectly and should never be installed together. Nothing errors; you just get doubled or contradictory behaviour. These overlaps come up again and again in group mod lists:

AreaWhat overlapsWhat you see
Inventory sizeTwo extended-inventory mods, or one plus an all-in-oneMissing rows, items vanishing into hidden slots
Container handlingQuick stack, sort and trash modsDoubled buttons, items moved twice
Shared chestsMulti-user chest plus a stacking mod that does not support itDesync, rejected moves
Crafting from chestsTwo craft-from-containers modsResources counted twice or not at all
Stack sizes, carry weightAn all-in-one plus a dedicated modOne config silently overrides the other
MapSeveral pin or minimap modsDuplicate pins, overlapping panels

Some authors document these clashes. The MultiUserChest page states that QuickStore, QuickStack and SimpleSort cause desyncs and will not start alongside it, and recommends Quick Stack Store Sort Trash Restock instead; that mod in turn declares itself incompatible with Trash Items because it already includes trashing. Read the "Incompatible" or "Known issues" section on every mod page before you add it, and check your existing list against it. Quality-of-life mods for groups goes through the common container and map mods and which ones sit together.

The all-in-one mods deserve their own warning. The Valheim Plus forks and similar packages change dozens of systems at once - stack sizes, building, crafting, map sharing, inventory. Adding any focused mod on top of one is a gamble, because the all-in-one probably already patches that area. If your group runs one, treat it as the base of the list and check every addition against its feature list.

Reading LogOutput.log properly#

Everything above depends on reading one file well. BepInEx writes BepInEx/LogOutput.log on every start, overwriting the previous one, so copy it before restarting if you want to compare runs. On a server you can also watch the same lines scroll in the console, though the file is easier to search.

A healthy start runs roughly in this order:

  1. The preloader and Doorstop lines. If the log stops here, BepInEx itself is broken - covered in server crashes on start.
  2. A Loading [Name Version] line for each plugin, in dependency order.
  3. Chainloader startup complete, after which the game takes over.
  4. Game lines: the world loading, the server registering, the join code on a crossplay server.

Everything between steps 2 and 3 is the mods' own start-up. A mod that loads but then throws an exception in its own Awake will be listed as loaded and still not work, so do not stop at the Could not load search - also search for Exception and [Error. Warnings are mostly noise; errors are worth reading every time. Reading BepInEx logs goes deeper into the preloader and Doorstop failures.

On a client, the same file lives in the r2modman profile folder rather than the game folder, which catches people out. r2modman's settings have a button to open the profile folder; the log is in its BepInEx subfolder.

Bisecting a broken mod set#

When the log does not name the culprit, halve the list. It feels slow and it is the fastest method there is: with 40 mods, six rounds leave one suspect. The steps:

  1. Work on a copy. Back up the world and the whole BepInEx folder first. Testing with half the content mods removed can delete their items and pieces from the world on save, so never bisect against the live world. A test server or a local copy of the world is the right place.
  2. Make the problem repeatable. Write down the exact action that fails: "crafting at the forge throws an error", "the server stops at chain loader". If you cannot trigger it on demand, you cannot bisect it.
  3. Keep the libraries. Jotunn, HookGenPatcher and other libraries stay in every round. You are testing the mods that use them.
  4. Remove half. Move half the remaining mods out of BepInEx/plugins into a folder outside it, such as plugins-disabled beside BepInEx. In r2modman, disable them instead.
  5. Test. If the problem is gone, the culprit is in the half you removed: put that half back and remove the other half. If the problem remains, it is in the half still installed.
  6. Repeat on the suspect half until one mod is left.
bash
# On a Linux server, park half the mods outside the plugins folder$ mkdir -p ~/server/plugins-disabled$ mv ~/server/BepInEx/plugins/{ModA,ModB,ModC,ModD}* ~/server/plugins-disabled/$ ls ~/server/BepInEx/plugins

Two complications. First, a conflict needs two mods, so the problem can disappear in both halves. When that happens, one suspect is in each half: keep one half fully installed and bisect the other until the problem returns, then you have the first mod; repeat the other way to find its partner. Second, a removed mod that others depend on takes its dependants with it. Check the log after each round for new Could not load lines so you know what was actually running.

On RE:NODE the file manager can move or rename files in BepInEx/plugins without an SFTP client, and the console shows the BepInEx lines as they arrive, so a bisect round is a move, a restart and a scroll. Take a backup from the Backups tab before the first round and lock it, so rotation cannot remove it while you are testing - see backups for how locking works.

Config conflicts and synced settings#

Some conflicts live in configuration rather than code. Two mods that both expose a stack-size or carry-weight setting will each apply theirs, and whichever runs last wins. The fix is to set the value in only one of them and leave the other at its default or disabled.

Synced configs add another layer. Mods that use ServerSync or Jotunn's config sync push the server's values to each client on connect, overriding the client's own file for as long as they are connected. So a player who edits their local config and sees no change is not seeing a bug: the server's value wins. The reverse is also true - editing the server's file is the only way to change a synced setting for everyone. Settings not marked as synced stay per player, and two players can legitimately have different values. The details, including locked configs and admin-only settings, are in ServerSync and config enforcement.

When you are bisecting, config files are a trap. A removed mod's .cfg stays in BepInEx/config, which is harmless, but a mod that reads another mod's settings can behave differently depending on which configs exist. If a problem survives every bisect round, try moving BepInEx/config aside entirely so every mod starts on its defaults. If that fixes it, the culprit is a setting, not a mod.

Preventing conflicts on a group server#

Most conflicts on group servers come from changing several things at once. A few habits stop most of them:

  • One change per restart. Add or update one mod, restart, test, then the next. If something breaks, you already know which change did it.
  • Read the changelog before updating. Authors note new dependencies and dropped compatibility there. A new hard dependency on a library you do not have will break the mod on a manually maintained server.
  • Keep a known-good copy. After each working state, archive BepInEx/plugins and BepInEx/config. Rolling back is then copying a folder, not remembering forty version numbers.
  • Prefer focused mods over overlapping ones. One mod per job. If two mods both offer a feature, turn it off in one of them.
  • Hold updates on patch day. A game patch can break patches in many mods at once, and that looks like a hundred conflicts when it is really one cause - what to do when a mod update breaks covers the waiting game.

The BepInEx server guide has the basics of the install itself if you are building a list from scratch.

FAQ#

How do I know which mod is crashing my Valheim server?

Open BepInEx/LogOutput.log and search for Could not load, then Exception. The stack trace of an exception usually contains the namespace of the mod that was running. If the log names nothing useful, bisect: remove half the mods, test, and keep halving the half that contains the problem.

Do I need to install dependencies by hand on a server?

Yes, unless you installed the server's mods with a manager that resolves them. Every hard dependency listed in a mod's Thunderstore page must be present in BepInEx/plugins at the required version or newer, otherwise BepInEx skips the mod at start-up.

Can two mods that patch the same thing work together?

Often, yes. Most patches only add behaviour after the game's method runs, and several of those coexist. Problems come when one mod replaces the original method entirely or rewrites its instructions, which is why mods touching the same area - inventory, crafting, building - are the first pair to test.

Why does a mod work for my friends but not on the server?

Usually because the server was set up by hand and is missing a library the friends' mod manager installed for them, or because the server still has an older copy of the mod in a subfolder. Check the server log for Could not load and Skipping lines.

Will removing a mod during testing damage my world?

It can. When a content mod is missing, the world cannot load its items or pieces, and saving drops them. Always bisect on a copy of the world and restore the backup afterwards, rather than testing on the world your group plays on.