Roblox Studio error

Cannot kick a non-local Player from a LocalScript

What Cannot kick a non-local Player from a LocalScript means in Roblox Studio, the three things that cause it with the code that triggers each, and the fix for each one.

Updated 5 November 20264 min readErrorLuauWritten by

In short

A LocalScript runs on one player's device, and the only player it may kick is that same player (Players.LocalPlayer). Calling Kick on anyone else from a LocalScript stops with this error. To kick another player, for example from an admin panel button, the LocalScript sends a request to the server through a RemoteEvent, and a server Script checks that the sender is allowed and then calls Kick.

  • Kicking is a server job. The button only asks; the server decides.
  • Check the sender's permission on the server, by UserId or group rank. Never trust a "you are an admin" flag sent by the client.
  • For a ban that lasts, use Players:BanAsync on the server rather than a kick.
On this page
  1. What it means
  2. Causes and fixes
  3. Fix it with RoCode
  4. Find the line
  5. Questions
  6. Sources

What the message means

Output (example)
Players.Builderman.PlayerGui.AdminPanel.KickButton.LocalScript:9: Cannot kick a non-local Player from a LocalScript

If a LocalScript could kick anyone, any player running a cheat could empty your server, because a cheater controls every LocalScript on their own device. So Roblox only lets a client remove itself.

Kicking yourself from a LocalScript is allowed and sometimes useful, for example after a client-side check fails, but it only ever affects the device the script runs on.

Causes and fixes

Three things cause this error in practice. Each one below has the smallest code that triggers it, then the fix.

An admin button kicks the target from its LocalScript

GUI buttons run LocalScripts, so the click handler is on the client. Finding the target with Players:FindFirstChild(name) works there, but Kick on that player does not.

Breaks LocalScript in the KickButton in StarterGui named KickButton
local Players = game:GetService("Players")

local button = script.Parent :: TextButton
local nameBox = button.Parent:WaitForChild("NameBox") :: TextBox

button.Activated:Connect(function()
	local target = Players:FindFirstChild(nameBox.Text)
	if target and target:IsA("Player") then
		-- Cannot kick a non-local Player from a LocalScript
		target:Kick("Kicked by an admin")
	end
end)

Move the kick to a server Script. The button's LocalScript only asks, with kickRequest:FireServer(nameBox.Text) on a RemoteEvent named KickRequest in ReplicatedStorage. The server checks who is asking against a list it keeps itself, checks the type of what was sent, and only then kicks. Without that check any player could fire the remote and kick anyone, because RemoteEvents in ReplicatedStorage are visible to every client.

Fixed Script in ServerScriptService named KickService
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local kickRequest = ReplicatedStorage:WaitForChild("KickRequest") :: RemoteEvent

-- UserIds allowed to kick. Kept on the server, where players cannot read or change it.
local ADMINS: { [number]: boolean } = {
	[156] = true,
}

kickRequest.OnServerEvent:Connect(function(sender: Player, targetName: unknown)
	if not ADMINS[sender.UserId] then
		return
	end
	if typeof(targetName) ~= "string" then
		return
	end
	local target = Players:FindFirstChild(targetName)
	if target and target:IsA("Player") and target ~= sender then
		target:Kick("You were removed by an admin.")
	end
end)

Put your own UserId in ADMINS (it is the number in the address of your Roblox profile page). The admin panel guide builds a full panel with ranks, kick and BanAsync, and the RemoteEvents guide explains the checks.

A client-side check kicks other players

A LocalScript that watches every player, for example a speed check or a ban list, and kicks the ones it does not like, runs into the same rule. It would also be easy to switch off, since it runs on a device the player controls.

Breaks LocalScript in StarterPlayerScripts named BanCheck
local Players = game:GetService("Players")

local BANNED_NAMES = { "SomeRuleBreaker" }

Players.PlayerAdded:Connect(function(player: Player)
	if table.find(BANNED_NAMES, player.Name) then
		-- Cannot kick a non-local Player from a LocalScript
		player:Kick("You are banned from this game.")
	end
end)

Run checks like this in a server Script, and check UserIds rather than names, because players can change their name.

Fixed Script in ServerScriptService named BanCheck
local Players = game:GetService("Players")

local BANNED_USER_IDS: { [number]: boolean } = {
	[123456789] = true,
}

Players.PlayerAdded:Connect(function(player: Player)
	if BANNED_USER_IDS[player.UserId] then
		player:Kick("You are banned from this game.")
	end
end)

For bans that last across servers, Players:BanAsync on the server stores the ban for you, as the admin panel guide shows.

A ModuleScript that kicks is required from a LocalScript

A ModuleScript runs wherever it is required. The same moderation module that works from a server Script fails when a LocalScript requires it and calls its kick function.

Breaks ModuleScript in ReplicatedStorage named Moderation
local Moderation = {}

function Moderation.remove(player: Player, reason: string)
	-- fine from a server Script; from a LocalScript, for anyone but LocalPlayer:
	-- Cannot kick a non-local Player from a LocalScript
	player:Kick(reason)
end

return Moderation

Keep moderation modules in ServerScriptService or ServerStorage, where LocalScripts cannot require them, and call them only from server Scripts.

Fixed ModuleScript in ServerScriptService named Moderation
local Moderation = {}

-- Lives in ServerScriptService, so only server Scripts can require it
function Moderation.remove(player: Player, reason: string)
	player:Kick(reason)
end

return Moderation

Fix it in your place

Paste the error, RoCode fixes it in your place

Copy the line from Output and paste it here. RoCode opens the script it names in the place you have open in Studio, works out which of the causes above it is, and edits the code there instead of handing you a snippet to paste.

For example: Players.Builderman.PlayerGui.AdminPanel.KickButton.LocalScript:9: Cannot kick a non-local Player from a LocalScript

RoCode is an AI agent for Roblox Studio: it reads the scripts in the place you have open, finds the line and edits it there, and every change is an undo point. It runs on Windows or macOS with a desktop browser. Free to start, with free credits every day.

How to find the line that causes it

  1. The path in the message names the LocalScript, often inside PlayerGui, which is where StarterGui's scripts run during play.
  2. Click the line in Output to open it at the Kick call, then move that call to a server Script as shown above.

Questions

Can a LocalScript kick a player?

Only its own player: Players.LocalPlayer:Kick("message") works. To kick anyone else, ask the server with a RemoteEvent.

How do I make a kick button for admins?

The button's LocalScript fires a RemoteEvent with the target's name. A server Script checks that the sender's UserId is on its admin list, checks the name is a string, finds the player and calls Kick.

Is hiding the admin button enough?

No. A cheater can fire your RemoteEvent without any button. The permission check has to be in the server Script that receives the event.

What is the difference between Kick and BanAsync?

Kick removes the player from this server only; they can join again. Players:BanAsync, called on the server, bans them from the experience for as long as you choose.

Can RoCode fix it?

Yes. Paste the Output line into RoCode. It reads your place, moves the kick to a server Script, adds the RemoteEvent and an admin check, and tells you what it changed.

Sources and further reading

How the code was checked: every block marked Fixed passes Luau's strict type checker against Roblox's API definitions (luau-lsp, 5 November 2026), and every block marked Breaks compiles and fails only when it runs. The message wording was checked against the message strings in Roblox Studio itself (macOS build installed 2 November 2026) and the Player:Kick reference on 5 November 2026. A type check catches misspelt APIs and wrong types, not game logic, so playtest in Studio before you publish.

More Roblox errors

All Roblox Studio errors

Stop hunting errors line by line.

RoCode reads the scripts in your open place, fixes the error where it happens and tells you what it changed. Free every day, no card required.