Fix "Failed to initialize plugin" NullReferenceException in Oxide plugins
The exception was thrown from the plugin's Init (or Loaded) method, so Oxide aborted loading the plugin. The usual cause is reading config before LoadConfig has assigned it, or accessing players/entities before the server is ready. Move that work into LoadConfig/Loaded/OnServerInitialized and null-check every lookup.
Failed to initialize plugin 'ServerRewards v1.0.0' (NullReferenceException: Object reference not set to an instance of an object) at Oxide.Plugins.ServerRewards.Init () [0x00017] in <8f3c1a2b4d5e4f6a9b0c1d2e3f4a5b6c>:0
Why it happens
Oxide calls Init early in the plugin lifecycle, before LoadConfig, OnServerInitialized and any player or entity is guaranteed to exist. If config is only assigned inside a custom loader that runs later, Init dereferences a null field and throws NullReferenceException. The same happens when Init iterates BasePlayer.activePlayerList, calls BasePlayer.FindByID, or touches BaseNetworkable.serverEntities during startup. Any exception in Init or Loaded makes Oxide print Failed to initialize plugin '<Name> v<Version>' and stop loading the plugin; the rest of the server keeps running. The stack trace points at the exact line, which is the fastest way to find the null reference.
How to fix it
- Read the stack trace: the line number after
[0x...]in the<Plugin>.Init ()frame is where the null was dereferenced. - Look for
config, referenced plugins ([PluginReference]), player lists, entity lookups orBaseNetworkable.serverEntitiesused inInitor a field initializer. - Guard
configwith a null check or move that logic intoLoadConfig/Loaded, which run after config is read. - Move entity and player work into
OnServerInitialized, where the world and player list exist. - Null-check every external lookup before use and return early instead of throwing.
- Save the file to trigger a reload (or run
oxide.reload ServerRewards). A successful load printsLoaded plugin <Title> v<Version> by <Author>; the initialize error and stack trace are gone.
Before and after
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("ServerRewards", "RustPluginGenerator", "1.0.0")]
[Description("Gives players points they can spend with a chat command")]
public class ServerRewards : RustPlugin
{
private class StoredData
{
public Dictionary<string, int> Points = new Dictionary<string, int>();
}
private class PluginConfig
{
[JsonProperty("Points per message")]
public int PointsPerMessage = 5;
[JsonProperty("Welcome message")]
public string Welcome = "Welcome, {0}!";
}
private PluginConfig config;
private StoredData data;
// BUG: reads config before LoadConfig runs
private void Init()
{
foreach (var player in BasePlayer.activePlayerList)
{
player.ChatMessage(string.Format(config.Welcome, player.displayName));
}
}
private void Loaded()
{
data = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
if (data == null) data = new StoredData();
}
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
config = Config.ReadObject<PluginConfig>();
if (config == null)
{
PrintWarning("Configuration file is invalid, using defaults");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Points"] = "You have {0} points."
}, this);
}
protected override void Unload()
{
data = null;
}
[ChatCommand("points")]
private void CmdPoints(BasePlayer player, string command, string[] args)
{
if (player == null || data == null) return;
int points;
if (!data.Points.TryGetValue(player.UserIDString, out points)) points = 0;
SendReply(player, lang.GetMessage("Points", this, player.UserIDString), points);
}
}
}using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("ServerRewards", "RustPluginGenerator", "1.0.0")]
[Description("Gives players points they can spend with a chat command")]
public class ServerRewards : RustPlugin
{
private class StoredData
{
public Dictionary<string, int> Points = new Dictionary<string, int>();
}
private class PluginConfig
{
[JsonProperty("Points per message")]
public int PointsPerMessage = 5;
[JsonProperty("Welcome message")]
public string Welcome = "Welcome, {0}!";
}
private PluginConfig config;
private StoredData data;
private void Init()
{
// Config and player lists are not ready here. Register nothing that needs them.
}
private void OnServerInitialized()
{
if (config == null || string.IsNullOrEmpty(config.Welcome)) return;
foreach (var player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected) continue;
player.ChatMessage(string.Format(config.Welcome, player.displayName));
}
}
private void Loaded()
{
data = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
if (data == null) data = new StoredData();
}
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<PluginConfig>();
if (config == null) throw new System.Exception();
}
catch
{
PrintWarning("Configuration file is invalid, using defaults");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Points"] = "You have {0} points."
}, this);
}
private void Unload()
{
if (data != null) Interface.Oxide.DataFileSystem.WriteObject(Name, data);
data = null;
}
[ChatCommand("points")]
private void CmdPoints(BasePlayer player, string command, string[] args)
{
if (player == null || data == null) return;
int points;
if (!data.Points.TryGetValue(player.UserIDString, out points)) points = 0;
SendReply(player, lang.GetMessage("Points", this, player.UserIDString), points);
}
}
}FAQ
Does this unload my plugin permanently?
No. Oxide leaves the plugin file in oxide/plugins but the plugin does not finish loading, so its hooks and commands are not registered. Fix the code and save; the automatic reload picks it up.
Why does it work after a server restart?
It usually does not — Init runs before the world is ready either way. If a restart seems to help, your code is racing something that becomes non-null later. Move the work to OnServerInitialized so the ordering is explicit.
Difference between Failed to initialize and Failed to call hook?
Failed to initialize plugin means the exception came from Init/Loaded and loading was aborted. Failed to call hook means the plugin loaded but a hook threw; the plugin stays loaded and the hook keeps firing.
Can I see the config value at startup?
Yes, after LoadConfig runs. Log it from Loaded (or OnServerInitialized) with Puts, not from Init, and only when you need to debug; avoid logging on every hook call.
Different error?
Paste the full console output and get the cause and a fix in plain English.
Open the error explainerSkip the debugging
Generated plugins are compiled before you get them, and compiler errors are fixed automatically.
Generate a plugin2 free plugins a month, no card.
Last updated Oct 26, 2026.
Get plugins that compile first time
Generate