FiveM Vehicle Scripts Troubleshooting FAQ: 12 Common Issues Fixed
Vehicle scripts drive half of the roleplay experience β spawning, customization, fuel, keys, garages. When any piece breaks, every player notices. This guide walks through the 12 most common vehicle script failures on ESX, QBCore, and QBox with diagnostic steps and working code examples.

Vehicle scripts drive half of the roleplay experience on a FiveM server. Spawning, customization, fuel, keys, garages β when any single piece breaks, every player notices within the first five minutes of a session.
This guide walks through the twelve vehicle script failures we see most often across ESX, QBCore, and QBox installations. Each section covers how to diagnose the root cause, the fix that resolves it in most cases, and the edge case that catches experienced admins.
Quick Diagnosis Table

Before diving into individual issues, match the symptom you see to the most likely root cause.
| Symptom | Most likely cause | First thing to check |
|---|---|---|
| Spawn command runs, nothing appears | Model not streaming | stream/ folder contents |
| Car spawns but drives like a default | Handling not applying | handlingName in handling.meta matches handlingId in vehicles.meta |
| Spawned car visible but transparent | Missing .ytd texture | Re-download resource |
| Keys don't work after buying | Shop missing key-assign event | Grep shop script for vehiclekeys event |
| Fuel stuck at 100% | Fuel script not running | Manually SetVehicleFuelLevel and observe |
| Garage doesn't save | DB schema mismatch | Server console for SQL errors |
| Damage resets on retrieve | Garage not saving health values | Inspect garage SQL columns |
| Nitro effect but no boost | Anti-cheat clamping power | Disable anti-cheat on staging |
| Lock does nothing | Player not recognized as owner | Check key system DB |
| Livery slot selectable, no visual | .ytd missing texture | Inspect .ytd with OpenIV |
| Performance mod has no effect | Vehicle model doesn't support mod | GetNumVehicleMods(veh, modType) |
| Speed reading nonsense | Double conversion | Search for * 3.6 duplicates |
Use this table as a triage filter. Once you've narrowed down the bucket, jump to the detailed section below.
1. Car Not Spawning
When a custom vehicle fails to spawn, the streaming system can't find or load the model. The first thing to verify is the resource structure:
my-vehicle/
βββ fxmanifest.lua
βββ stream/
β βββ mycar.yft -- Vehicle model
β βββ mycar.ytd -- Vehicle textures
β βββ mycar_hi.yft -- High-detail model
βββ data/
βββ vehicles.meta
βββ carvariations.meta
βββ handling.meta
Then confirm fxmanifest.lua registers the meta files correctly:
fx_version 'cerulean'
game 'gta5'
files {
'data/vehicles.meta',
'data/carvariations.meta',
'data/handling.meta',
}
data_file 'VEHICLE_METADATA_FILE' 'data/vehicles.meta'
data_file 'CARCOLS_FILE' 'data/carvariations.meta'
data_file 'HANDLING_FILE' 'data/handling.meta'
Fix checklist, in order:
.yftand.ytdfiles present instream/vehicles.metadeclared with theVEHICLE_METADATA_FILEdata_file type (case-sensitive)- Resource
ensure-ed inserver.cfg - Spawn name matches
modelNamein vehicles.meta exactly - Server-side asset cache cleared after adding the vehicle β delete
cache/on the server host if the vehicle still won't spawn after other fixes
If the vehicle appears for admins but not regular players, a streaming budget limit has been hit. Check onesync_distanceCullingLimit and the server's streaming-memory settings.
2. Handling File Not Applying
If a vehicle spawns but drives like a default car, the handling data isn't loading. The fix is almost always a name mismatch between files:
<!-- handling.meta -->
<Item type="CHandlingData">
<handlingName>MYCAR</handlingName>
<!-- This name must match vehicles.meta's handlingId -->
</Item>
<!-- vehicles.meta -->
<handlingId>MYCAR</handlingId>
If the names match and handling still feels wrong, another resource is globally overriding handling. Common culprits are "realistic handling" mods that patch every vehicle in the game. Grep your resource folders for SetVehicleHandlingFloat or SetVehicleHandlingField calls and identify the override source.
Handling data is loaded once when the resource starts β restart the resource after any handling.meta edit.
3. Vehicle Key System Broken
Key systems track which player owns which vehicle by plate. If keys don't work after buying or spawning a vehicle, the shop script isn't triggering the key-assignment event correctly.
Debug by dropping a print into the key script's receive handler:
-- In your key script's server.lua
RegisterNetEvent('vehiclekeys:server:assign', function(plate, citizenid)
print(('[keys] assign request: plate=%s cid=%s'):format(
plate or 'nil', citizenid or 'nil'
))
-- ...rest of logic
end)
If the event fires with plate=nil, the vehicle shop is passing the wrong value. If the event never fires at all, the shop isn't triggering it β some shops call it client-side and expect a server ack, others go direct to server.
Three common root causes:
- Empty plate β the shop fires the assign event before the vehicle has a plate set.
- Wrong citizenid format β QBCore expects
"ABC12345", ESX expects the identifier. - Race condition β the assign event fires faster than the vehicle entity is registered server-side.
4. Fuel Not Draining
Fuel scripts run a client-side loop that reads engine RPM and decrements fuel based on load. To confirm your fuel script is actually running, add a debug thread:
Citizen.CreateThread(function()
while true do
local ped = PlayerPedId()
local veh = GetVehiclePedIsIn(ped, false)
if veh ~= 0 then
local rpm = GetVehicleCurrentRpm(veh)
local fuel = GetVehicleFuelLevel(veh)
print(('[fuel-debug] rpm=%.2f fuel=%.2f'):format(rpm, fuel))
end
Wait(1000)
end
end)
If RPM reads correctly but fuel never drops, the fuel script's consumption loop isn't executing. Most fuel scripts skip boats and aircraft by default β check the script's config for Config.VehicleClasses or a similar allowlist.
Test directly by forcing a fuel change:
SetVehicleFuelLevel(veh, 50.0)
- If the value stays at 50%: fuel script isn't running.
- If the value jumps back to 100%: something else is continuously refilling fuel. Look for other resources calling
SetVehicleFuelLevelin a loop.
5. Speedometer Wrong Values
The speed conversion math must match your server's display preference. GetEntitySpeed returns meters per second β it never returns km/h or mph directly:
local speed_ms = GetEntitySpeed(vehicle)
local speed_kmh = speed_ms * 3.6
local speed_mph = speed_ms * 2.237
If your speedometer shows unrealistically high numbers (500+ km/h in a standard car), the conversion is being applied twice β once in Lua and again in the NUI JavaScript. Find the duplicate and remove one.
If the speedometer reads zero while driving, the script isn't detecting that the player is in a vehicle. Check the GetVehiclePedIsIn call β it should run every poll, not be cached from a previous frame.
6. Custom Vehicles Invisible
An invisible vehicle that you can still enter and drive has a missing or corrupt .ytd texture file. The .yft model loads (which is why collision and controls still work), but the vehicle renders transparent without its textures.
Fix steps:
- Re-download the vehicle resource from its original source
- Verify both
.yftand.ytdexist instream/ - Check for a
_hi.yfthigh-detail model β some vehicle packs expect one and fail silently without it - Open the
.ytdin OpenIV to confirm textures actually exist inside it (occasionally a.ytdis valid but empty)
7. Garage Not Saving
Garage persistence failures are database-schema mismatches. The garage script tries to INSERT or UPDATE a row with specific columns, and if any column is missing or of the wrong type, the SQL silently fails on most hosts.
-- Verify the row actually wrote
SELECT * FROM player_vehicles WHERE plate = 'ABC123';
-- Inspect the schema
DESCRIBE player_vehicles;
Common columns a modern garage expects:
| Column | Type | Purpose |
|---|---|---|
plate | VARCHAR(10) | Vehicle plate, primary lookup |
owner / citizenid | VARCHAR(50) | Who owns the vehicle |
vehicle | TEXT | Serialized vehicle properties (JSON) |
mods | TEXT | Performance + visual mods (JSON) |
state | INT | 0 = parked, 1 = out, 2 = impound |
garage | VARCHAR(50) | Which garage it's stored at |
fuel | INT | 0β100 fuel level |
engine | FLOAT | Engine health |
body | FLOAT | Body health |
Enable SQL error logging in your server config to catch the exact failure reason.
8. Vehicle Damage Not Persisting
Damage persistence requires the garage script to store and restore three health values:
-- On park: save these values
GetVehicleEngineHealth(veh) -- Engine damage, max 1000
GetVehicleBodyHealth(veh) -- Body damage, max 1000
GetVehiclePetrolTankHealth(veh) -- Fuel tank damage, max 1000
-- On retrieve: restore them
SetVehicleEngineHealth(newVeh, engineHealth)
SetVehicleBodyHealth(newVeh, bodyHealth)
SetVehiclePetrolTankHealth(newVeh, tankHealth)
If damage resets on retrieve, the garage script is either not saving these fields (check SQL INSERT columns) or not calling the setters when spawning from storage. Visual deformation (dents, scratches) requires SetVehicleDeformationFixed or storing the deformation map β most free garage scripts skip this.
9. Nitro Not Working
Nitro scripts apply a temporary engine power multiplier:
SetVehicleEnginePowerMultiplier(vehicle, 50.0)
If nitro activates (sound and visual effects play) but the vehicle doesn't accelerate, something is resetting the power multiplier mid-boost. The usual culprits are server-side anti-cheat scripts that clamp engine power, or another handling-modifying resource running its own loop.
Diagnose by logging the multiplier every tick during boost:
CreateThread(function()
while boostActive do
print(('[nitro-debug] power=%.2f'):format(GetVehicleEnginePowerMultiplier(vehicle)))
Wait(100)
end
end)
If the value resets to 1.0 between your applies, another script is overriding it. Disable anti-cheat on a staging server to confirm.
10. Vehicle Lock/Unlock Issues
Lock state is controlled by SetVehicleDoorsLocked. If the keybind does nothing, isolate where the chain breaks:
- Keybind not registered β test with a
print()inside the handler. - Player not recognized as owner β query the key system's DB directly.
- Event not reaching server β add logging on both client and server.
- Lock state desync β a vehicle may be locked server-side but display as unlocked client-side on respawn.
Many lock scripts require the vehicle to be networked (via NetworkRegisterEntityAsNetworked) before lock state replicates to other players.
11. Livery Not Showing
Liveries need two things to line up: the livery texture inside the vehicle's .ytd, and a reference in carvariations.meta matching the texture name exactly. If the livery slot is selectable in the mod menu but the vehicle shows the default paint, one of the two is missing.
Open the .ytd with OpenIV or RageLib and check that all referenced livery textures exist. The names in carvariations.meta must match case-sensitively, with no spaces:
<livery>
<Item>mycar_livery_1</Item>
<Item>mycar_livery_2</Item>
</livery>
12. Performance Mods Not Applying
Vehicle tuning uses indexed mod categories. The important ones for performance:
| Mod type | Category | Levels |
|---|---|---|
| 11 | Engine | 0β3 |
| 12 | Brakes | 0β2 |
| 13 | Transmission | 0β2 |
| 15 | Suspension | 0β3 |
| 16 | Armor | 0β4 |
| 18 | Turbo | 0 = off, 1 = on |
SetVehicleMod(vehicle, 11, 3, false) -- Engine level 4 (0-indexed)
Not every vehicle supports every mod category. Use GetNumVehicleMods to check what's available:
local engineLevels = GetNumVehicleMods(vehicle, 11)
print(('Engine levels available: %d'):format(engineLevels))
If the function returns 0, that vehicle's model doesn't expose engine upgrades at all β the handling.meta and vehicles.meta define which categories the vehicle supports.
Recommended Scripts
When you need vehicle scripts that just work β framework-native, performance-tested, documented β check the VertexMods catalog:
- FiveM Vehicle Scripts β Premium and free vehicle resources
- FiveM Car Mods β Custom vehicles with handling files
- Best FiveM Scripts 2026 β Top-rated scripts across all categories
- FiveM Troubleshooting Guide β Broader troubleshooting playbook
- FiveM Error Codes Fixes β Decoding common error messages
Frequently Asked Questions
Why isn't my custom car spawning in FiveM?
Custom vehicles fail to spawn when the model isn't streaming correctly. Verify the resource contains .yft and .ytd files in the stream/ folder, that fxmanifest.lua declares vehicles.meta as a data_file with the correct VEHICLE_METADATA_FILE type, that the resource is ensured in server.cfg, and that both client and server cache are cleared. Also confirm the spawn name matches modelName in vehicles.meta exactly, case-sensitive.
Why isn't my handling file applying to vehicles?
Handling files don't apply when three things break: the handling.meta data_file entry is missing from fxmanifest.lua, the handlingName in handling.meta doesn't match the handlingId in vehicles.meta, or another resource is globally overriding handling data. Fix them in that order and restart the resource β handling is loaded once at resource start, not per spawn.
Why is the vehicle key system broken?
Key system failures almost always come from the vehicle shop or garage not triggering the key-assignment event after spawn. The key script expects an exact plate string, and if the spawning script passes an empty plate or fires the event before the vehicle exists, keys never assign. Add a print() inside the key script's event handler to confirm it receives the right plate.
Why isn't fuel draining in my vehicles?
Fuel scripts read RPM via GetVehicleCurrentRpm and decrement fuel based on engine load. If fuel stays at 100%, either the fuel script's loop isn't running, it doesn't support your vehicle type (most scripts skip boats and aircraft by default), or another script is continuously refilling fuel. Test by manually calling SetVehicleFuelLevel(veh, 50.0) β if fuel stays at 50%, the fuel script isn't running; if it jumps back to 100%, something is refilling it.
Why is the speedometer showing wrong speed values?
Speed discrepancy is always a unit conversion bug. GetEntitySpeed returns meters per second. Multiply by 3.6 for km/h or by 2.237 for mph. If your speedometer shows impossibly high numbers, the conversion is being applied twice. If it shows zero, the script isn't detecting the player is in a vehicle β usually a broken GetVehiclePedIsIn check.
Why are custom vehicles invisible after spawning?
An invisible drivable vehicle has a missing or corrupt .ytd texture file. The model loads (so collision and controls work) but renders transparent without textures. Re-download the vehicle resource, verify both .yft (model) and .ytd (textures) are in stream/, and check that a _hi.yft high-detail variant exists if the vehicle pack expects one.
Why isn't my garage saving vehicles?
Garage save failures are database-schema mismatches. The garage script tries to INSERT or UPDATE a row with specific columns (mods, state, garage, plate, owner) and if any column is missing or of the wrong type, the SQL silently fails. Check the server console for SQL errors, and run DESCRIBE player_vehicles to verify the schema matches the garage script's expectations.
