Billboard GUI not parenting to Character.Head

My billboard gui isn’t parenting to the character’s head. Can someone explain why?

Script:

local ms = game.ReplicatedStorage.Tags
local marks = ms:Clone()

game.Players.PlayerAdded:Connect(function(p)
	p.CharacterAdded:Connect(function(c)
		p.Chatted:Connect(function(msg)
			
			marks.Parent = c.Head
			
			
			local sod = 12648334
			local sodrankdtousecommand = 245
			local td = 12648341
			local tdranktousecommand = 246
			local sd = 12648370
			local sdranktousecommand = 244
			local cpd = 12648361
			local cpdranktouescommand = 243

			if p:GetRankInGroup(sod) >= sodrankdtousecommand or p:GetRankInGroup(td) >= tdranktousecommand or p:GetRankInGroup(cpd) >= cpdranktouescommand or p:GetRankInGroup(sd) >= sdranktousecommand or p.TeamColor == BrickColor.new("Really red") and msg == "cpdtag ".. p.Name then
				marks.CPDMark.Visible = true
			elseif msg == "revoke cpdtag ".. p.Name then
				marks.CPDMark.Visible = false
			end

			if p:GetRankInGroup(sod) >= sodrankdtousecommand or p:GetRankInGroup(td) >= tdranktousecommand or p:GetRankInGroup(cpd) >= cpdranktouescommand or p:GetRankInGroup(sd) >= sdranktousecommand or p.TeamColor == BrickColor.new("Really red") and msg == "sdtag " .. p.Name then
				marks.SDMark.Visible = true
			elseif msg == "revoke sdtag ".. p.Name then
				marks.SDMark.Visible = false
			end

			if p:GetRankInGroup(sod) >= sodrankdtousecommand or p:GetRankInGroup(td) >= tdranktousecommand or p:GetRankInGroup(cpd) >= cpdranktouescommand or p:GetRankInGroup(sd) >= sdranktousecommand or p.TeamColor == BrickColor.new("Really red") and msg == "tdtag ".. p.Name then
				marks.TDMark.Visible = true
			elseif msg == "revoke tdtag ".. p.Name then
				marks.TDMark.Visible = false
			end

			if p:GetRankInGroup(sod) >= sodrankdtousecommand or p:GetRankInGroup(td) >= tdranktousecommand or p:GetRankInGroup(cpd) >= cpdranktouescommand or p:GetRankInGroup(sd) >= sdranktousecommand or p.TeamColor == BrickColor.new("Really red") and msg == "sodtag ".. p.Name then
				marks.SODMark.Visible = true
			elseif msg == "revoke sodtag ".. p.Name then
				marks.SODMark.Visible = false
			end
		end)
	end)
end)

Shuffle around some variables, and a WaitForChild for good measure:

local ms = game.ReplicatedStorage.Tags

game.Players.PlayerAdded:Connect(function(p)
	p.CharacterAdded:Connect(function(c)
		local marks = ms:Clone()
		marks.Parent = c:WaitForChild("Head")
		p.Chatted:Connect(function(msg)
local rs = game:GetService("ReplicatedStorage")
local tags = rs:WaitForChild("Tags")
local players = game:GetService("Players")

players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		plr.CharacterAppearanceLoaded:Connect(function(char)
			local marks = tags:Clone()
			plr.Chatted:Connect(function(msg)
				marks.Parent = char.Head
				local sod = 12648334
				local sodrankdtousecommand = 245
				local td = 12648341
				local tdranktousecommand = 246
				local sd = 12648370
				local sdranktousecommand = 244
				local cpd = 12648361
				local cpdranktouescommand = 243

				if plr:GetRankInGroup(sod) >= sodrankdtousecommand or plr:GetRankInGroup(td) >= tdranktousecommand or plr:GetRankInGroup(cpd) >= cpdranktouescommand or plr:GetRankInGroup(sd) >= sdranktousecommand or plr.TeamColor == BrickColor.new("Really red") and msg == "cpdtag ".. plr.Name then
					marks.CPDMark.Visible = true
				elseif msg == "revoke cpdtag ".. plr.Name then
					marks.CPDMark.Visible = false
				end

				if plr:GetRankInGroup(sod) >= sodrankdtousecommand or plr:GetRankInGroup(td) >= tdranktousecommand or plr:GetRankInGroup(cpd) >= cpdranktouescommand or plr:GetRankInGroup(sd) >= sdranktousecommand or plr.TeamColor == BrickColor.new("Really red") and msg == "sdtag " .. plr.Name then
					marks.SDMark.Visible = true
				elseif msg == "revoke sdtag ".. plr.Name then
					marks.SDMark.Visible = false
				end

				if plr:GetRankInGroup(sod) >= sodrankdtousecommand or plr:GetRankInGroup(td) >= tdranktousecommand or plr:GetRankInGroup(cpd) >= cpdranktouescommand or plr:GetRankInGroup(sd) >= sdranktousecommand or plr.TeamColor == BrickColor.new("Really red") and msg == "tdtag ".. plr.Name then
					marks.TDMark.Visible = true
				elseif msg == "revoke tdtag ".. plr.Name then
					marks.TDMark.Visible = false
				end

				if plr:GetRankInGroup(sod) >= sodrankdtousecommand or plr:GetRankInGroup(td) >= tdranktousecommand or plr:GetRankInGroup(cpd) >= cpdranktouescommand or plr:GetRankInGroup(sd) >= sdranktousecommand or plr.TeamColor == BrickColor.new("Really red") and msg == "sodtag ".. plr.Name then
					marks.SODMark.Visible = true
				elseif msg == "revoke sodtag ".. plr.Name then
					marks.SODMark.Visible = false
				end
			end)
		end)
	end)
end)

You only ever cloned 1 pair of the tags and then parented them to the first loaded character of the first player which joined. Now a new pair is created every time a character loads and they are parented to the “Head” of that player’s character.

Doesn’t work. I tested it in a different template, but still it doesn’t work.

You must have set up the BBGui incorrectly then, or something is incorrectly referenced.

Nope, my BBGui is correctly fine. It does work in the game, but for some reason, whenever a player joined, the ImageLabels are visible, even though the visibility is set to false.