Fix CS0115: no suitable method found to override (Oxide)
You put the override keyword on a hook method that has no virtual base method to override. Oxide hooks are found by name on RustPlugin, not by overriding anything, so remove override and the plugin compiles.
Error while compiling ServerGreeter: [1] 'ServerGreeter.OnServerInitialized()': no suitable method found to override at 18:30
Why it happens
The compiler error means the method carries the override modifier but no base class member with that signature is virtual or abstract. In Oxide, lifecycle methods such as OnServerInitialized, Init, Loaded, Unload, OnPlayerConnected and chat/console commands are not overrides. Oxide looks up hook methods by name when the event fires and calls the private method with matching parameters. The only members of RustPlugin you legitimately override are the config methods (LoadDefaultConfig, LoadConfig, SaveConfig) and message loading (LoadDefaultMessages), because those declarations in the base class are virtual. The usual trigger is a developer copying a pattern from a tutorial or another plugin where someone wrote private override void OnServerInitialized(), or adding override to silence a warning the IDE gave about a method that hides something. The compiler reports the line and column of the method signature, not the body, so look at the declaration line.
How to fix it
- Open the file at the line given in the console message (here line 15, column 33).
- Remove the
overridekeyword from the hook method signature. Keep itprivateand keep the parameter list exactly as the hook requires. - Save the file. Oxide reloads the edited plugin automatically; you can also run
oxide.reload ServerGreeter. - Check the console: the compile error disappears and you get
Loaded plugin Server Greeter v1.0.0 by RustPluginGenerator(or the title and author from your[Info]attribute). No line means the plugin loaded. - If you still see CS0115 on a different method, that method is also an Oxide hook or a mistyped name. Compare the name against the documented hook; hooks are case- and spelling-sensitive and none of them are virtual.
Before and after
using System.Collections.Generic;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Server Greeter", "RustPluginGenerator", "1.0.0")]
[Description("Greets every player who joins the server.")]
public class ServerGreeter : RustPlugin
{
private const string PermGreet = "servergreeter.greet";
private void Init()
{
permission.RegisterPermission(PermGreet, this);
}
// CS0115: override on a hook that has no virtual base method
public override void OnServerInitialized()
{
Puts("Server Greeter initialized.");
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null || !player.IsConnected) return;
if (!permission.UserHasPermission(player.UserIDString, PermGreet)) return;
player.ChatMessage("Welcome to the server, " + player.displayName + "!");
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Welcome"] = "Welcome to the server, {0}!"
}, this);
}
}
}using System.Collections.Generic;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Server Greeter", "RustPluginGenerator", "1.0.0")]
[Description("Greets every player who joins the server.")]
public class ServerGreeter : RustPlugin
{
private const string PermGreet = "servergreeter.greet";
private void Init()
{
permission.RegisterPermission(PermGreet, this);
}
// Hooks are found by name; never marked override
private void OnServerInitialized()
{
Puts("Server Greeter initialized.");
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null || !player.IsConnected) return;
if (!permission.UserHasPermission(player.UserIDString, PermGreet)) return;
player.ChatMessage(string.Format(lang.GetMessage("Welcome", this, player.UserIDString), player.displayName));
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Welcome"] = "Welcome to the server, {0}!"
}, this);
}
}
}FAQ
Which methods in an Oxide plugin are actually overrides?
Only the config and message methods declared virtual in RustPlugin: LoadDefaultConfig, LoadConfig, SaveConfig, LoadDefaultMessages. Everything else a plugin exposes to the server is a hook discovered by name at runtime, so it must not carry override.
Will removing override break the hook?
No. Oxide calls hooks by name and signature, not through virtual dispatch. A plain private void OnServerInitialized() is invoked exactly like an overridden method would be, provided the parameter types match what Oxide passes.
Why did my IDE suggest adding override?
Some IDE analyzers warn when a method name matches a member in a base type. If you have a local method named like a base member you may see a hiding warning. For Oxide hooks the correct action is to leave the method as-is or rename unrelated helpers; do not add override.
Does Carbon handle this differently?
Carbon compiles the same file with the same C# rules, so override on a hook fails there too. The Carbon console prints the CS code alongside its own message format, but the fix is identical: remove the modifier.
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