Rust Plugins Broken After Update: How to Fix Oxide and Carbon Plugins
After a monthly Rust update, plugins break because the game's code changed underneath them: members were renamed, types changed, or the method an Oxide hook patches was altered. Update Oxide or Carbon first, then read the compile errors, check which hooks changed, and fix or replace the plugins that still fail.
8 min readUpdated Oct 26, 2026
After a monthly Rust update, fix broken plugins in this order: install the Oxide or Carbon build that matches the new game version, restart, read the compile errors in the console, check which hooks changed, and then repair or replace each plugin that still fails. Most breakage falls into a small number of patterns, and each one is recognizable from the log.
Why plugins break after an update
Two separate things can go wrong, and they look different.
- The plugin no longer compiles. The plugin references a class, field, method or type that Rust renamed, removed or changed. Oxide prints a compile error and skips that file. The other plugins still load.
- The plugin compiles but does nothing, or throws at runtime. A hook's injection point moved or was removed, or the arguments it passes changed. The plugin loads normally but a feature is dead, or you get
Failed to call hookmessages.
Compile failures are loud and easy to find. Dead hooks are quiet, so you need to test features.
Step 1: Update Oxide or Carbon first
Before touching any plugin, update the framework. Oxide patches game methods to create hooks, so a build made for the previous Rust version can fail on the new one. Many "broken plugin" reports disappear once the framework matches the game.
- Update the Rust server through SteamCMD.
- Install the Oxide or Carbon release for that Rust version. See install Oxide on a Rust server and Oxide vs Carbon if you are choosing between them.
- Start the server and run
oxide.versionto confirm what is running. - Run
oxide.pluginsto list which plugins loaded and which did not.
Carbon loads Oxide plugins and accepts the oxide.* commands, so the same workflow applies. Core framework updates often arrive a few hours to a day after the game update, so if no matching build exists yet, waiting is the correct fix.
Step 2: Read the compile errors
A failing plugin prints Error while compiling <PluginName>: followed by numbered messages in the form [1] <message> at <line>:<column>. The full text, including the CS code, is also written to oxide/logs (carbon/logs on Carbon). Start with the first error of each plugin, because later errors are often consequences of it.
| Error | Typical meaning after an update |
|---|---|
| CS1061 | A member you call no longer exists on that type, usually renamed or removed |
| CS0117 | A static member or enum value no longer exists |
| CS0029 / CS0266 | A type changed, so the value cannot be assigned as before |
| CS1503 | An argument type no longer matches a method parameter |
| CS1501 / CS7036 | A method gained or lost parameters |
| CS0246 | A type or namespace moved or was removed |
Renamed or removed members: CS1061 and CS0117
When Rust renames a field or method, every plugin using the old name fails with CS1061 (instance members) or CS0117 (static members and enum values). The message names the type and the missing member, for example 'BasePlayer' does not contain a definition for 'oldName'.
The fix is to find what the member is called now (see step 4) and replace it. If the error mentions a generic constraint, the variant CS1061 with where clauses applies.
Type changes: CS0029 and NetworkableId
The best-known type change is entity IDs. net.ID is no longer a plain ulong; it is a NetworkableId struct, and the numeric value is read through net.ID.Value. Old code like this fails:
ulong id = entity.net.ID; // CS0029: cannot convert NetworkableId to ulongThe corrected version:
ulong id = entity.net.ID.Value;The same applies to comparisons and dictionary keys. If you store entity IDs in data files, store the ulong from .Value. See CS0029 NetworkableId for more cases.
Player IDs follow a similar pattern: player.userID converts implicitly to ulong, but when you need a real ulong value, for example for a method parameter or a dictionary key, use player.userID.Get(). A mismatch between ulong and string shows up as CS1503; use player.UserIDString where a string is required.
Signature changes: CS1501 and CS7036
If a game method gained a parameter, calls with the old argument list fail with CS1501 or CS7036. Add the new arguments, using the decompiler to see what they mean.
Step 3: Check removed or changed hooks
A plugin can compile and still lose a hook. Each month the updates page lists hooks that were added, removed or changed. Compare it against the hooks your plugins use.
What a change can look like:
- A hook disappears. The method is never called. Features that depend on it silently stop.
- The signature changes. Oxide only calls your method if every argument is an instance of the parameter type you declared. If a parameter type no longer matches what the hook passes, your method is skipped. Methods may declare fewer parameters than the hook passes, so trimming a parameter is sometimes enough.
- The return behavior changes. Many hooks are patched so that any non-null return cancels the action, including
false. Check the individual hook page, such as CanBuild or OnEntityTakeDamage, before assuming what a return value does.
If your console shows a deprecated hook warning, replace the hook now. It still works for the moment, but it is slated for removal. For background, read Oxide hooks explained.
To find dead hooks without reading the code, test each feature in-game after an update. A short checklist per plugin (run the command, take damage, loot a crate, build a structure) catches silent failures that logs never mention.
Step 4: Find the new API with a decompiler
Documentation lags behind the game. The reliable source is the game itself. The server's managed assemblies sit in RustDedicated_Data/Managed, mainly Assembly-CSharp.dll. Open it in a .NET decompiler such as ILSpy or dnSpy and look at the type from the error message.
A practical routine:
- Search for the type named in the error, for example
BasePlayer. - Look for members with similar names or the same type. Renames usually keep the type and behavior.
- If the member is gone, read the decompiled body of a related method to see how Rust now does it.
- For a changed signature, check the callers inside the game code to learn what the new arguments mean.
- Make the smallest change that compiles, then test the behavior.
Keep a decompiled copy of the previous version when you can. Comparing the old and new assemblies is much faster than searching blindly. See rust plugin development setup for configuring references in your editor.
Step 5: Reload one plugin at a time
You do not need a restart after each fix. Save the file in oxide/plugins and it reloads automatically, or run:
oxide.reload MyPluginWatch for the Loaded plugin <Title> v<Version> by <Author> line. There is no separate "compiled successfully" message, so that line is your confirmation. After it appears, test the feature. For more on reading logs, see debugging Rust plugins.
Runtime errors after an update
If the plugin loads but throws, the log shows messages like Failed to call hook 'OnEntityTakeDamage' on plugin 'Name v1.0.0' (NullReferenceException: ...). After updates, these usually come from a value that used to be set and is now null, or a cast that no longer holds. See NullReferenceException in hooks and InvalidCastException in hooks.
Two other post-update patterns:
- Old data files. Saved data containing entity IDs or removed item names can cause JSON reader errors or key lookups that fail. After a wipe, resetting the data file is often correct.
- Removed items or prefabs.
ItemManager.CreateByNamereturns null for an unknown shortname, andGameManager.server.CreateEntitycan return null for a prefab path that no longer exists. Check both results.
Defensive patterns that survive updates
You cannot predict renames, but you can make plugins fail gently.
Null-check everything from the game. Hook arguments and nested members can be null more often after changes.
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
if (entity == null || info == null) return null;
var attacker = info.InitiatorPlayer;
if (attacker == null) return null;
return null;
}Check item and prefab lookups.
var item = ItemManager.CreateByName(config.RewardShortname, 1);
if (item == null)
{
PrintWarning($"Unknown item shortname: {config.RewardShortname}");
return;
}
player.GiveItem(item);Put the warning in startup code or a rare path, never in frequently firing hooks such as damage or gather.
Keep game-specific values in config. Shortnames and prefab paths belong in the configuration file, so admins can correct them without editing code. See plugin config files.
Use the narrowest API. Prefer well-established members such as UserIDString, net.ID.Value and ShortPrefabName over internal fields, which change more often.
Isolate optional integrations. When calling another plugin through [PluginReference], always handle the reference being null, since the other plugin may be the one that broke. See calling other plugins.
What to do when a plugin is abandoned
If the author does not update and the fix is not small:
- Fix the few failing lines yourself, using the steps above.
- Check whether the plugin is a uMod plugin rather than an Oxide plugin or needs a missing dependency, which can look like update damage.
- Replace it with a recipe from this site, such as gather multiplier, stack sizes or no decay, or generate a new one with the plugin generator.
How this site re-checks its plugins each month
Plugins generated here follow strict rules so that they are easy to re-verify: only documented members, null checks on every hook parameter, no reflection and no reliance on private game fields. After each monthly Rust update, the hook signatures and game members used by our recipes are compared against the new game build. Hooks that were removed or changed are listed on the updates page, and affected recipes are corrected before the report goes out.
That does not replace testing on your own server. Your plugin mix, config and data files are unique, so run through the checklist below after each update.
Post-update checklist
- Update the server, then Oxide or Carbon, and confirm with
oxide.version. - Run
oxide.pluginsand note anything missing or failing. - Fix compile errors one plugin at a time, first error first.
- Compare your plugins' hooks against the updates page.
- Test every feature in-game, especially anything driven by hooks.
- Clear or migrate data files that store entity IDs.
- Watch the console for the first hour for runtime errors and slow hook warnings (see performance).
On wipe day this runs together with the other tasks in the wipe day plugin checklist.
FAQ
Why do plugins break after a Rust update but not after a restart?
Plugins are compiled against the game's assemblies at load time. A Rust update replaces those assemblies, so code that referenced a renamed member or changed type no longer compiles. A plain restart changes nothing, which is why a plugin that worked yesterday can fail right after a forced wipe-day update.
Can a plugin load without errors and still be broken?
Yes. If Oxide's patch for a hook no longer applies, the hook silently never fires, or it fires with different arguments. The plugin loads and prints Loaded plugin, but its feature does nothing. Test every feature in-game after an update, not just the console output.
Do I need to recompile plugins manually?
No. Oxide and Carbon compile .cs files from the plugins folder at startup. To retry one plugin without restarting, run oxide.reload <Name>, or save the file again, since saving a file in the plugins folder triggers a reload.
Is it safe to run an old Oxide build on a new Rust version?
No. Oxide patches game methods, and a build made for an older game version can fail to apply patches or throw errors in core hooks. Install the Oxide or Carbon build released for your Rust version, and do not combine old builds with a new client or server branch.
What should I do when the plugin author has gone away?
Read the compile errors, fix the renamed members yourself if the changes are small, or regenerate a replacement with the plugin generator. Keep a copy of the original file so you can compare behavior. For larger plugins, consider splitting out the broken feature rather than rewriting everything.
More guides
- CovalencePlugin vs RustPlugin: Differences and Which to Use4 min read
- How to Debug a Rust Oxide Plugin: Compile Errors, Exceptions and Slow Hooks10 min read
- How to Give Items to Players in a Rust Plugin (Oxide/Carbon)5 min read
- How to Install Oxide on a Rust Dedicated Server (Windows and Linux)7 min read
Skip the C#: describe your plugin
Open generator