FiveM vehicle keys: can't drive your own car or lock it? Fix it

How FiveM vehicle key systems work: plate lists, giving keys after a spawn or purchase, locking with SetVehicleDoorsLocked, and why you lose access to your own car.

Typical symptoms:

text
You get in your own car: "Vehicle is locked", the engine will not start,
or the key script says you do not have the keys.

A car that worked yesterday and is now locked to its owner is almost always a key list problem, not a game bug. This article explains how key systems work, how to give keys after a spawn or a purchase, and what to check when you cannot drive your own vehicle.

How a key system works

The game itself has no keys. It only has a lock state on each vehicle. A key resource adds the rest on top of it:

  1. It stores which plates each player has a key for. The plate is the identity of the car, since the entity handle changes every time the car is spawned.
  2. It locks or unlocks the vehicle with natives.
  3. It blocks the engine, or the door, for players who are not on the list.

The lock native is client side:

lua
-- 1 = unlocked, 2 = locked
SetVehicleDoorsLocked(vehicle, 2)

local status = GetVehicleDoorLockStatus(vehicle)
print(status)

SetVehicleDoorsLocked sets the state and GetVehicleDoorLockStatus reads it back. Besides 1 and 2 there are other states, such as one that locks the car for the player only. For a simple lock and unlock you need just those two.

Tip: locking a car does not stop a player from breaking a window or pulling the driver out of an unlocked NPC car. Anything beyond the lock state is up to the key script.

Who owns the list

Where the list lives decides what breaks after a restart:

  • Memory only. The list is rebuilt when a player joins, from the vehicles they own in the database. If the script restarts while you play, the list is empty until you reconnect.
  • Database or item based. Keys are items in the inventory, with the plate in the item metadata. The key survives a restart, but a changed plate breaks it.
  • Owner check. The script compares the player identifier with the owner of the plate in owned_vehicles (ESX) or player_vehicles (QBCore and QBox). No separate list exists.

Find out which one your resource uses before debugging. The article on saving owned vehicles in the database covers the tables most key scripts read.

Give keys after a spawn or a purchase

Whenever your own script creates a vehicle for a player, the key resource does not know about it. You have to tell it, in this order:

  1. Create the vehicle.
  2. Set the plate with SetVehicleNumberPlateText.
  3. Call the key resource's export or event with that plate.
lua
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false)
SetVehicleNumberPlateText(vehicle, plate)

-- the name of this call depends on your key resource: check its documentation
exports['your_key_resource']:GiveKeys(plate)

your_key_resource and GiveKeys are placeholders. The real name is in the documentation of the resource you use. If it is an event, the same rule applies: pass the plate, not the entity handle.

For a purchase the plate must be stored with the new row in the database, and the keys given at the same moment, or the buyer drives out of the dealership with a car that no longer matches anything. See spawning vehicles for the plate handling.

Lockpicking and hotwiring

These are features of the key script, not of the game. The usual logic is:

  • A player who is not on the key list tries to enter a locked car. The script runs a skill check or a progress bar.
  • On success it unlocks the car with SetVehicleDoorsLocked(vehicle, 1). For hotwiring it also lets the engine start for that session, typically by remembering the plate in a temporary list.
  • On failure it can alert the police or break the tool.

If you build your own, keep the result decision on the server. A client that decides alone whether it is allowed to unlock any car can be abused with a mod menu.

Cannot drive your own car

Go through these causes in order:

The key list was lost. A script restart, a crash or a refresh; restart of the key resource empties a memory based list. Reconnect, or trigger the script's own refresh.

The plate changed. A plate is stored in three places: the vehicle in game, the key list or key item, and the database row. If a script changes one of them (a plate changer, a fake plate item, a tuning script) the others stop matching. Compare the plate on screen with the one in your table:

sql
SELECT owner, plate FROM owned_vehicles WHERE plate LIKE '%MIC%';

Plates also differ in whitespace. MIC 001 and MIC001 are two different plates for most scripts, so trim and compare in the same format everywhere.

The wrong owner. The row has an old identifier or citizenid, so the owner check fails. This is the same cause as a car missing from the garage.

The car was spawned by another script. Anything created without a key call is locked to everyone. Add the keys call where it is spawned.

Two key resources. Running two key scripts that both lock the car makes it flip between states. Keep one.

Test quickly in game

When you doubt the lock state itself, read it from the client:

lua
RegisterCommand('lockstate', function()
    local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
    if vehicle == 0 then return end
    print('lock status', GetVehicleDoorLockStatus(vehicle), GetVehicleNumberPlateText(vehicle))
end, false)

It prints the state and the plate. If the state is 1 and you still cannot drive, the key script is blocking the engine, not the lock.

Checklist

Symptom Fix
Locked out after a restart The key list is in memory: reconnect or let the script rebuild it from owned vehicles
Spawned car is locked to you Call the key resource's export or event with the plate after SetVehicleNumberPlateText
Car bought but no keys Give keys at purchase time and store the same plate in the database
Keys stopped working after a plate change Update the plate in the game, the key list and the database together
Plate looks right but does not match Check spaces and letter case, use one format everywhere
Door state is 1 but the engine stays off The key script blocks the engine: check its list, not the lock
Car flips between locked and unlocked Two key scripts are running: remove one

Quick answers

Why can't I drive my own car after a restart?

Most key scripts keep the list of keys in memory. After a restart or a script restart the list is empty, so the car is locked or the engine refuses to start. The script has to rebuild the list from your owned vehicles when you load in.

How do I give keys to a car I spawned with my own script?

Call the export or event of your key resource with the plate, after you have set the plate. Every key script names this call differently, so read its documentation instead of copying a call from another server.

Does changing the plate break my keys?

Yes, on any system that matches keys by plate. If the plate changes in the game but not in the key list and the database, the vehicle no longer matches a key. Change all three together.

Scripts that skip this problem

Advanced BoostingTablet-driven vehicle boosting: contracts from class D to S+, crews and a live queue.View script →Car BombPlant, detect and defuse vehicle bombs — with a detonator phone and a C4 minigame.View script →Chameleon Paints82 colour-shifting chameleon paints in one click-to-apply menu.View script →

Keep reading