Skip to content
RustPluginGenerator
Runtime errorOxide + Carbon

Fix "Plugin 'AutoBroadcast' is using the Lang API but has no messages registered" (Oxide)

Oxide prints this when your plugin calls lang.GetMessage for a key that was never registered, usually because LoadDefaultMessages does not exist or does not call lang.RegisterMessages. Register a defaults dictionary in LoadDefaultMessages (or call lang.RegisterMessages once before use) and every lookup resolves.

Server console
Plugin 'AutoBroadcast' is using the Lang API but has no messages registered

Why it happens

The message comes from Oxide's language layer. When a plugin asks Oxide to resolve a lang key, Oxide checks whether that plugin has any registered messages at all. If the plugin has never called lang.RegisterMessages, there is nothing to resolve against, so Oxide logs the warning once and the lookup returns nothing useful.

Common triggers:

  • The plugin has a Msg helper that calls lang.GetMessage(key, this, userId) but no protected override void LoadDefaultMessages() method.
  • LoadDefaultMessages exists but registers an empty dictionary, or registers keys with names that differ from the ones used at call sites.
  • Keys were registered in a Init/Loaded hook that returns early (for example when a config check fails) before the registration line runs.
  • The plugin was copied from another plugin and the LoadDefaultMessages block was dropped while the Msg helper remained.

The plugin keeps running; the warning is a signal that every player-facing string it sends is empty or missing.

How to fix it

  1. Add protected override void LoadDefaultMessages() to the plugin class.
  2. Inside it call lang.RegisterMessages(new Dictionary<string, string> { ... }, this); with every key your code passes to lang.GetMessage.
  3. Keep key names identical between the dictionary and call sites; a typo produces an empty string, not this warning, so check both lists.
  4. If the plugin registers messages conditionally, move the registration so it always runs on load, before any timer or command can call Msg.
  5. Optionally create oxide/lang/en/<PluginName>.json; Oxide writes the defaults there on first run and lets you edit text without recompiling. Note Carbon uses carbon/lang/en/.
  6. Confirm with oxide.reload AutoBroadcast. A clean reload prints Loaded plugin AutoBroadcast v1.0.0 by RustPluginGenerator and no Lang API line in the console or oxide/logs.

Before and after

BeforeFails
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("AutoBroadcast", "RustPluginGenerator", "1.0.0")]
    [Description("Broadcasts a message to all online players on a timer")]
    public class AutoBroadcast : RustPlugin
    {
        private Timer broadcastTimer;

        private string Msg(string key, string userId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, userId), args);
        }

        private void OnServerInitialized()
        {
            broadcastTimer = timer.Every(300f, Broadcast);
        }

        private void Broadcast()
        {
            if (BasePlayer.activePlayerList.Count == 0)
            {
                return;
            }

            Server.Broadcast(Msg("Broadcast", null, "Welcome to the server"));
        }

        private void Unload()
        {
            if (broadcastTimer != null)
            {
                broadcastTimer.Destroy();
            }
        }
    }
}
AfterFixed
using System;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("AutoBroadcast", "RustPluginGenerator", "1.0.0")]
    [Description("Broadcasts a message to all online players on a timer")]
    public class AutoBroadcast : RustPlugin
    {
        private Timer broadcastTimer;

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Broadcast"] = "{0}",
                ["NoPlayers"] = "Nobody is online to receive the broadcast."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, userId), args);
        }

        private void OnServerInitialized()
        {
            broadcastTimer = timer.Every(300f, Broadcast);
        }

        private void Broadcast()
        {
            if (BasePlayer.activePlayerList.Count == 0)
            {
                return;
            }

            Server.Broadcast(Msg("Broadcast", null, "Welcome to the server"));
        }

        private void Unload()
        {
            if (broadcastTimer != null)
            {
                broadcastTimer.Destroy();
                broadcastTimer = null;
            }
        }
    }
}

FAQ

Does this warning stop the plugin from working?

No. The plugin stays loaded and the hook or command still runs. The problem is that the lang lookup has no table to read from, so player-facing text is empty or falls back to the raw key. Fix the registration before players see blank chat lines.

I registered messages in Init and still see the warning. Why?

Check whether Init returns early (for example on a missing dependency) or runs after the first lookup. Move lang.RegisterMessages into LoadDefaultMessages, which Oxide calls during plugin load, and remove any duplicate registration from Init to avoid overwriting lang files.

Where do the lang files live?

Oxide writes defaults to oxide/lang/en/<PluginName>.json the first time the plugin registers messages. Carbon uses carbon/lang/en/<PluginName>.json. Editing that file changes text without recompiling; delete it to regenerate defaults after you add new keys.

Does calling lang.GetMessage from a static method cause this?

A static context cannot pass this, so the plugin instance is unknown and the registration lookup fails. Move the helper into the plugin class as an instance method, or store a static reference to the plugin instance and pass it to lang.GetMessage.

Different error?

Paste the full console output and get the cause and a fix in plain English.

Open the error explainer

Skip the debugging

Generated plugins are compiled before you get them, and compiler errors are fixed automatically.

Generate a plugin

2 free plugins a month, no card.

Last updated Oct 26, 2026.

Get plugins that compile first time

Generate