FiveM HUD Scripts Troubleshooting FAQ: 12 Common Issues Fixed
When a HUD script breaks on your FiveM server, every player sees it within seconds. This guide walks through the 12 most common HUD failures — invisible HUDs, broken speedometers, framework mismatches, FPS drops — with diagnostic steps and copy-paste fixes for ESX, QBCore, and QBox.

HUD scripts are the most visible resource on a FiveM server. When an inventory script misbehaves, a handful of players notice. When the HUD fails, everyone sees it within seconds — and they open a ticket immediately.
This guide walks through the twelve HUD failure modes that appear most often on ESX, QBCore, and QBox servers. Each section covers how to diagnose the issue, the fix that solves it 90% of the time, and the trap that causes the remaining 10%.
Quick Diagnosis Table

Before working through individual issues, match the symptom you see to the most likely root cause. Almost every HUD bug falls into one of these buckets.
| Symptom | Most likely cause | First thing to check |
|---|---|---|
| HUD completely invisible | NUI load failure | F8 console for Could not find resource ui page |
| HUD visible but all values empty/zero | Framework mismatch | Which framework the HUD was built for |
| HUD values updating slowly | Polling interval too long | Search for Wait( in client.lua |
| HUD disappears on vehicle enter/exit | Broken event listener | IsPedInAnyVehicle usage in HUD code |
| Minimap gone | HUD hides the default radar | DisplayRadar calls in HUD |
| FPS drops near menus | NUI focus conflict | SetNuiFocus calls across scripts |
| HUD off-screen or wrong size | Hardcoded px positions | CSS uses px instead of vw/vh |
| Keybind does nothing | Command not registered | RegisterKeyMapping in fxmanifest |
| HUD works offline, fails on server | fx_version / game mismatch | fx_version in fxmanifest.lua |
Use this table as a triage filter. Once you've narrowed to a bucket, jump to the section below.
1. HUD Invisible or Not Showing
The most common HUD failure is the entire interface failing to render. This is almost always a NUI problem, not a Lua problem — which is why it's invisible rather than throwing obvious script errors.
Open the F8 console and search for any of these patterns:
Could not find resource ui page
NUI: failed to load
SCRIPT ERROR: @your-hud/client.lua:XX
Error loading script web/dist/index.html
Fix checklist, in order:
- Confirm the HUD resource contains a built UI directory (
ui/,web/dist/, or similar). Modern HUDs built with a JS framework need a build step — runningnpm install && npm run buildinside the resource folder is not optional. - Check
fxmanifest.luahas the correctui_pagepath pointing to the builtindex.html, not the source file. - Verify the resource starts after your framework in
server.cfg. A HUD that loads before QBCore will fail to fetch player data. - Check resource ordering for dependencies — some HUDs depend on
ox_liborqb-corebeingensure-ed first.
If the HUD worked previously and just stopped, the most likely change is a framework update that renamed an event or export the HUD listens to. Roll the framework back, or check the HUD's release notes.
2. Minimap Not Displaying Correctly
Custom HUDs almost always hide the default GTA minimap and render their own styled version. If the minimap disappears entirely after installing a new HUD, the HUD is calling DisplayRadar(false) without providing a replacement.
To confirm:
-- Drop into client.lua or a debug resource
DisplayRadar(true)
If the minimap returns, the HUD is the cause. Two fixes:
- Enable the HUD's custom minimap — most HUDs have a config option like
Config.CustomMinimap = truethat must be flipped on. - Disable the radar hide — open the HUD's client.lua, find
DisplayRadar(false), and comment it out if you prefer the default.
Some HUDs also reposition the default minimap. If yours is visible but in the wrong corner, look for SetMinimapComponentPosition calls.
3. Speedometer Not Working
Speedometers rely on GetEntitySpeed(), a client-side native that returns raw meters per second. If the speedometer shows zero even while driving, debug the underlying value before blaming the HUD:
Citizen.CreateThread(function()
while true do
local ped = PlayerPedId()
local veh = GetVehiclePedIsIn(ped, false)
if veh ~= 0 then
local mps = GetEntitySpeed(veh)
local kmh = mps * 3.6
local mph = mps * 2.237
print(('Speed: %.1f m/s | %.1f km/h | %.1f mph'):format(mps, kmh, mph))
end
Wait(500)
end
end)
If this prints correct values but the HUD doesn't update, the bug is in the NUI bridge — the Lua side reads speed correctly but fails to send it to the HTML via SendNUIMessage. Open the F8 NUI devtools (nui_devtools), watch the message stream, and verify the HUD is actually receiving updates.
If the Lua side prints zeroes while driving, the issue is a broken GetVehiclePedIsIn check. Some HUDs cache the vehicle handle once and never update it.
4. Health and Armor Bars Wrong
Incorrect health and armor come from polling intervals that are too slow, or from the HUD reading cached values instead of native calls.
The sweet spot is 200–500ms polling. Slower than that misses rapid changes in combat. Faster than that — especially every-frame reads — destroys FPS because each read triggers a NUI message and a DOM update.
Citizen.CreateThread(function()
while true do
Wait(250) -- the sweet spot
local ped = PlayerPedId()
SendNUIMessage({
type = 'stats',
health = GetEntityHealth(ped) - 100, -- FiveM health baseline is 100
armor = GetPedArmour(ped)
})
end
end)
Note the - 100 — FiveM health natives return 100–200, not 0–100. If the HUD shows health starting at 100% when you're at full health, the HUD is dividing by 200 instead of subtracting the baseline.
5. Status Indicators Not Updating (Hunger/Thirst)
Hunger and thirst depend entirely on the framework's needs system. This is the single most common cause of HUD failures across the community — users install a QBCore HUD on an ESX server (or vice versa) and everything except status works, because the framework-specific events never fire.
-- QBCore pattern
RegisterNetEvent('QBCore:Player:Data', function(PlayerData)
SendNUIMessage({
type = 'needs',
hunger = PlayerData.metadata.hunger,
thirst = PlayerData.metadata.thirst
})
end)
-- ESX pattern
TriggerEvent('esx_status:getStatus', 'hunger', function(status)
SendNUIMessage({ type = 'needs', hunger = status.getPercent() })
end)
If your framework is QBox, the QBCore pattern works unchanged — QBox is event-compatible with QBCore on the needs surface. Before blaming the HUD, confirm which framework's events it listens to.
6. HUD Conflicting With Other UI
When the HUD blocks interaction with inventory, phone, or menu scripts, the culprit is almost always NUI focus. Only one NUI frame should capture mouse input at a time, and SetNuiFocus(true, true) is what captures it.
Audit the HUD's client.lua:
grep -n "SetNuiFocus" client.lua
A passive, display-only HUD should never call SetNuiFocus(true, true). Interactive HUDs (settings menus, emote wheels) should only hold focus while the menu is open and release it on close.
If the HUD is grabbing focus legitimately but never releasing it, look for missing SetNuiFocus(false, false) calls in the close handler.
7. HUD Causing FPS Drops
High-frequency DOM manipulation is the number one cause of HUD-related FPS drops. Every time the HUD updates a value, the browser engine recalculates layout and repaints. If this happens every frame (~16ms), performance suffers even on powerful clients.
Performance budget for a modern HUD:
| Metric | Budget | Notes |
|---|---|---|
| Poll interval | ≥200ms | Faster than 100ms is almost always wasted |
| DOM elements | <100 | Deep trees are slow to repaint |
| CSS box-shadow | Static only | Never on animated elements |
| CSS filter: blur | Static only | Same — very expensive on every repaint |
| Animation properties | transform, opacity only | These skip layout |
| NUI messages/sec | <20 | Batch multiple values into one message |
Move your biggest offenders first. Swapping a left: 200px animation for transform: translateX(200px) can recover 10–20 FPS on mid-range clients.
8. NUI Errors in Console
NUI errors in the F8 console mean the HUD's web interface failed. The most common cause is a missing build step — modern HUDs shipping with a React or Vue frontend require npm run build inside the resource folder before first start.
Check fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
ui_page 'web/dist/index.html' -- this file must actually exist
files {
'web/dist/**/*'
}
If web/dist/index.html doesn't exist, no UI will load. Run the HUD's documented build command, then restart the resource.
9. Keybind Toggle Not Working
If pressing the HUD toggle key does nothing, isolate whether the command fires at all:
RegisterCommand('togglehud', function()
print('HUD toggle triggered')
end, false)
RegisterKeyMapping('togglehud', 'Toggle HUD', 'keyboard', 'F7')
Restart the resource, press F7, and watch F8. If the print fires, the command is registered correctly and the bug is in the HUD's message-send side. If the print does not fire, another script already registered the same command name, or the HUD's fxmanifest is missing the keybind entirely.
Check /resmon for duplicate command registrations, or search all scripts for RegisterKeyMapping collisions.
10. HUD Positioned Wrong
Hardcoded pixel positions break across different monitor sizes. A HUD designed at 1920×1080 will render off-screen or cluster into one corner on 2560×1440 or ultrawide displays.
/* Bad: breaks on non-1080p */
.hud-container {
left: 20px;
bottom: 200px;
width: 400px;
}
/* Good: scales to any resolution */
.hud-container {
left: 1.5vw;
bottom: 12vh;
width: 25vw;
}
Viewport-relative units (vw, vh) scale with the client's resolution automatically. Percentage-based widths scale with the parent container. Both are drop-in replacements for px in 95% of HUD layouts.
11. HUD Not Scaling on Different Resolutions
Closely related to positioning — the same root cause produces both symptoms. Fixed-pixel fonts and element sizes crush readability on low-resolution clients and look oversized on 4K.
A well-built HUD uses clamp() to set reasonable min/max bounds:
.hud-speedometer {
font-size: clamp(14px, 1.5vw, 22px);
}
This stays between 14px and 22px regardless of viewport size. If the HUD you're troubleshooting ships with a resolution or scale config option, set it explicitly rather than leaving it on auto.
12. Framework Integration Errors
If the HUD throws errors about missing exports (attempt to call a nil value (field 'PlayerData'), No such export 'GetCoreObject'), it's incompatible with your framework version.
Check three things, in order:
- Framework compatibility declared by the HUD. Most HUD scripts are QBCore-only, ESX-only, or ship with separate builds per framework. Using a QBCore HUD on an ESX server is not a fixable misconfiguration — it requires a full rewrite of the HUD's framework bridge.
- Framework version. QBCore had a major breaking change between v1.2 and v2.0 around player data exports. A HUD built for v1.2 will error on v2.0 without code changes.
- Dependencies. Many modern HUDs require
ox_liborqb-coreto beensure-ed before the HUD resource. Check the HUD's README for a required resources list.
When in doubt, install the HUD on a clean staging server with only the framework and its direct dependencies. If it works there and fails on your live server, something in your resource stack is the cause.
Recommended Scripts
When you need a HUD that just works — performance-tested, framework-native, documented — the VertexMods catalog is a good starting point:
- FiveM HUD Scripts — Premium and free HUD resources, filterable by framework
- Best FiveM Scripts 2026 — Top-rated scripts across all categories
- FiveM Troubleshooting Guide — The broader troubleshooting playbook
- FiveM Error Codes Fixes — Decoding every common error message
Frequently Asked Questions
Why is my FiveM HUD invisible or not showing?
An invisible HUD is almost always a NUI rendering failure or a missing build step. Open the F8 console, look for errors containing 'NUI' or 'Could not find resource ui page', then verify the HUD has a built ui/ or web/dist/ directory and that fxmanifest.lua points at the right ui_page. Also confirm the HUD starts after your framework in server.cfg.
Why is the minimap not displaying correctly with my custom HUD?
Most custom HUDs call DisplayRadar(false) to hide the default minimap and render their own. If the minimap disappears entirely, the HUD is hiding it without providing a replacement. Either enable the HUD's custom minimap in its config, or force the default back with DisplayRadar(true) to test whether the HUD is the cause.
Why is the speedometer not working in my HUD?
Speedometers read from GetEntitySpeed() on the client. If speed stays at zero, check (1) the player is actually in a vehicle when the value reads, (2) the HUD converts raw m/s to km/h or mph correctly (multiply by 3.6 for km/h, 2.237 for mph), and (3) the NUI message bridge is actually sending updates — a print statement in Lua confirms the native works even if the HUD silently fails.
Why are health and armor bars showing wrong values?
Wrong health and armor values usually mean the HUD polls GetEntityHealth() and GetPedArmour() too slowly, or caches stale values. Poll every 200–500ms. Anything slower misses rapid changes during combat. Anything faster (every frame) destroys FPS.
Why aren't hunger and thirst indicators updating?
Hunger and thirst come from your framework's needs system. QBCore exposes them via the QBCore:Player:Data event; ESX uses esx_status events; QBox follows QBCore's pattern. If the HUD was built for the wrong framework, these indicators will never update even though everything else works.
Why is my HUD conflicting with other UI scripts?
UI conflicts happen when multiple scripts call SetNuiFocus(true, true) at once, or fight over the same z-index. Only one NUI frame should capture mouse input at a time. The HUD should only ever set focus for interactive panels (menus, settings), never for passive display.
Why is my custom HUD causing FPS drops?
HUD-induced FPS drops come from three sources: polling natives every frame (use 200ms+ intervals), unoptimized CSS (box-shadow and filter:blur on animated elements), and DOM thrashing (updating many elements on every tick). Use transform translateX() instead of left/top for animations — transforms skip layout recalculation.

