The FiveM error catalog
Errors are not the enemy. A red line in the console is the server telling you exactly what is wrong and exactly where. The only skill you are missing is reading it. In this lesson you learn to read an error like an address, then you get a catalog of the eight errors every FiveM beginner hits, each with its exact console text, what it actually means, and the single fix that clears it.
Read an error before you fix it
A FiveM error is not a wall of noise. It is a small structured report, and it almost always names three things: which resource broke, which file the problem is in, and which line number to open. Find those three and you have the address. The fix is usually obvious once you are standing at the right door.
Here is a real one as it appears in the txAdmin Live Console. Read it top to bottom before you read the breakdown under it.
Now decode it line by line. Every error you will ever read has these same parts.
[script:my_bank]is the resource. The text in brackets is the folder name of the resource that threw the error. This is where you go. Not a random file somewhere on your server: this folder.server/main.lua:14is the file and line. Openserver/main.luainsidemy_bankand go to line14. That is the exact line the server choked on.attempt to index a nil value (global 'QBCore')is the meaning. It names the culprit: the variableQBCorewasnilwhen the code tried to use it. The thing in parentheses is the name of whatever was empty.stack tracebackis the trail. It lists the chain of calls that led to the error, newest first. For a beginner the top line of the traceback is usually the only one you need, because that is the actual line that failed.
That is the whole skill. Resource, file, line, meaning. The catalog below gives you the meaning and the fix for the eight you will meet first, but you find every one of them the same way: read the brackets, open the file, jump to the line.
The console prints [script:my_bank] server/main.lua:14: attempt to index a nil value. Where do you go and what do you read?
Open the my_bank resource (the name in brackets), open server/main.lua inside it, and go to line 14. Read that exact line: something on it is nil when the code expects a value. The error even names which thing is nil in the parentheses at the end. You do not search the whole server. The error already gave you the resource, the file, and the line. That three-part address is the single most useful thing in any FiveM error message.
The catalog
Below are the eight errors that stop beginners, in the order you tend to meet them: manifest problems that stop a resource loading, then runtime nil-value errors, then dependency and database and config problems. Each one gives you the exact console text, what it means, and the fix.
1. Could not load resource / failed to load script
This is a manifest problem. The resource never even started, because fxmanifest.lua is wrong or points at a file that is not there.
Two root causes sit behind this message. The first is a manifest that does not parse. The most common version is the singular versus plural directive trap: the singular client_script and server_script take exactly one filename as a string, while the plural client_scripts and server_scripts take a Lua table in curly braces. Mix them up and the manifest silently drops files or refuses to load.
-- WRONG: singular directive given two files. The second is ignored or errors.
server_script 'a.lua', 'b.lua'
-- WRONG: plural directive without a table.
server_scripts 'a.lua'
-- CORRECT: singular for one file.
server_script 'a.lua'
-- CORRECT: plural for many, wrapped in a table. Globbing needs this form too.
server_scripts {
'a.lua',
'b.lua',
'shared/*.lua'
}The second root cause is a path in the manifest that points at a file that does not exist. Look at the mockup above: the manifest asked for server/mian.lua but the file on disk is server/main.lua. A typo or a renamed file gives you Failed to load script. Every file you name in the manifest must physically exist at that exact path. Fix the name in the manifest or rename the file, then restart the resource.
2. attempt to index a nil value
This is the runtime error you saw in the reading section. It means you used the dot, colon, or bracket operator on something that was nil. You tried to reach into a value that was empty.
The name in parentheses, here QBCore, is the thing that was nil. There are two distinct causes, and the file above is server/main.lua, so the first one bites even when qb-core is fully loaded.
The first cause is calling a client-only function on the server. QBCore.Functions.GetPlayerData() with no argument is client-only: it returns the local player's data and is documented only in the Client Function Reference. There is no "current player" on the server, so on the server it is nil no matter what your load order is. The server way is to look up the player by their source with QBCore.Functions.GetPlayer(source) and then read Player.PlayerData.
-- WRONG (in server/main.lua): GetPlayerData() with no source is CLIENT-ONLY.
-- On the server there is no "current player", so this is nil regardless of load order.
local QBCore = exports['qb-core']:GetCoreObject()
local money = QBCore.Functions.GetPlayerData().money -- indexing nil here
-- FIX (server side): look the player up by source, then read PlayerData.
-- Guard QBCore too, so a not-yet-loaded core object cannot crash you.
if QBCore and QBCore.Functions then
local Player = QBCore.Functions.GetPlayer(source)
local money = Player and Player.PlayerData.money or 0
endThe second, separate cause is load order: even the correct server call breaks if you index QBCore before qb-core has started, because the export returned nothing. That is why the guard above checks if QBCore and QBCore.Functions then and why you make sure the resource that provides the value is started before yours (see error 4). So the fix is two parts: use the right side's API (GetPlayer(source) on the server, GetPlayerData() on the client), and guard before you index so an empty object stops the code politely instead of crashing it.
3. attempt to call a nil value (the export or event)
Almost the same words as the last one, but a different operator. Here you tried to call something, with parentheses, that does not exist on this side. The function, export, or event you named is nil.
There are four usual causes, and one of them is the single biggest source of confusion in FiveM. A client_script runs on every player's game. A server_script runs once on the server. A native or export that exists on one side is nil on the other. PlayerPedId is a client native, so calling it in a server_script gives you exactly the second line above.
-- WRONG (in a server_script): PlayerPedId is a CLIENT native, so it is nil here.
local ped = PlayerPedId()
-- 'attempt to call a nil value (field DoThing)':
-- resourceA is not started, or the export name is mistyped.
exports['resourceA']:DoThing()Work through the four causes in order:
- Side mismatch. A client native called in a
server_script, or the reverse. Match the call to the right side. - Resource not started.
exports['resourceA']:DoThing()isnilifresourceAis not running. Ensure it inserver.cfg. - Typo. The export or event name is misspelled on one side. The names must match exactly, character for character.
- Framework not initialized yet. You called it before the resource that defines it had finished loading.
4. Missing dependency / resource not started
A resource needs another resource that is not running. Either you declared the dependency in the manifest and it is missing from server.cfg, or it failed to start, or it starts after the resource that needs it.
In a manifest you declare what must load first with the dependencies key. Note the key name and the table form.
fx_version 'cerulean'
game 'gta5'
server_script 'server.lua'
-- These resources must be started BEFORE this one.
dependencies {
'oxmysql',
'ox_lib'
}The fix lives in server.cfg, and order matters. Use ensure (it starts a resource if it is not already running) and list dependencies above the resources that use them. Databases and libraries go near the top.
# Load order is top to bottom. Dependencies first, dependents below them.
ensure oxmysql
ensure ox_lib
ensure qb-core
ensure my_bankTwo operational notes that catch people. After you add a brand-new resource folder you must run refresh in the console so the server notices it exists, then ensure or start it. And status lists everything currently running, which is how you confirm a dependency actually started instead of assuming it did.
5. oxmysql: no such table / connection_string
Database errors come in two flavours, and telling them apart saves you an hour. One means the database connection itself failed. The other means the connection is fine but a table is missing. oxmysql is the Overextended (community) MySQL library; it reads its credentials from the mysql_connection_string convar in server.cfg.
Unable to establish a connection means oxmysql never reached the database at all. The convar is missing or malformed, the MariaDB or MySQL service is not running, the credentials are wrong, or the database name does not exist. This is a config problem, not a code bug. Set the convar correctly in server.cfg. There are two accepted formats.
# URI format (most common).
set mysql_connection_string "mysql://root:mypassword@localhost:3306/mydatabase"
# If the password contains reserved characters like ; , / ? : @ & = + $ #
# the URI form breaks. Switch to the key=value form instead.
set mysql_connection_string "host=localhost;user=root;password=P@ss=word;database=mydatabase"
# No password at all? Omit the field. Do NOT leave password= blank.
set mysql_connection_string "mysql://root@localhost/mydatabase"ER_NO_SUCH_TABLE / no such table is the opposite situation: the connection works fine, but the table the script asked for was never created. Almost every script that uses a database ships a .sql schema file. If you never imported it, the tables do not exist. The fix is to import that .sql file into your database once. Open your database tool (HeidiSQL is the common one), select your database, and run the script's .sql file against it.
A quick way to confirm the import landed: list the tables and look for the one the error named.
If bank_accounts shows up in that list, the no such table error is gone. If it does not, the import did not run against this database.
6. sv_enforceGameBuild mismatch
This one often does not look like an error at all. sv_enforceGameBuild locks your server to a specific GTA V game build so that DLC assets load. If a player's game data does not match, or the build is wrong for your assets, you get a connect error or, worse, silent failures.
The meaning: the build number in server.cfg does not match what the connecting client has, or it does not match the build your DLC vehicles, weapons, and clothing were made for. The sneaky version of this bug has no error message at all: a DLC vehicle simply never spawns, because the build that ships it is not enforced. Set the build in server.cfg to match your assets. This is a startup-only setting, so you set it before the server boots.
# Lock the game build so DLC assets load. The value must match what
# your scripts and assets were built for. This is set at startup only.
sv_enforceGameBuild 3258 # example build; 2802 and 3095 are common older ones7. Duplicate resource
FiveM identifies a resource by its folder name, not its full path. If the same folder name exists in two places anywhere under resources, they collide and one refuses to load.
The cause is almost always a copy. You dragged a resource into a second category folder, or unzipped a download on top of an existing one, and now my_bank exists twice. Because FiveM keys on the folder name, the path does not save you.
resources/
[core]/
my_bank/ <- one copy here
[standalone]/
my_bank/ <- a second copy with the SAME folder name -> collisionThe fix is to delete or rename one of the two folders so the name is unique across the whole resources tree, then refresh and ensure the one you kept.
How it works
You can now find any error and you have the catalog. This section explains the one idea underneath most of them, so the next unfamiliar error is one you can reason about instead of search for.
Why so many errors say "nil"
nil is Lua's word for nothing, for a value that was never set. The two most common runtime errors, "attempt to index a nil value" and "attempt to call a nil value", are both the same root event: you reached for something that was not there. The difference is only the operator. Indexing uses a dot, colon, or bracket to reach into a value. Calling uses parentheses to run a value as a function. Both fail the same way when the value is nil, and both name the empty thing in parentheses so you know what was missing.
The reason this happens so often in FiveM specifically is the client and server split. The same word can be a real function on one side and nil on the other. So when you see a nil-value error, your first two questions are always: is this thing defined on the side I am calling it from, and has the resource that provides it actually started yet?
Why load order is half the battle
A lot of nil-value errors are not really code bugs. They are timing bugs. Your code is correct, but it ran before the thing it needed existed. If my_bank starts before oxmysql, then every database call in my_bank reaches for an export that is not there yet, and you get a nil-value error that looks like broken code but is actually a wrong line order in server.cfg.
That is why ensure and order in server.cfg matter so much. Databases and libraries first, frameworks next, your own resources last. Get the order right and a surprising number of mysterious errors simply never appear.
Your resource throws 'attempt to index a nil value (global QBCore)' on boot, but the code is identical to a working server. What do you check before touching the code?
Check the load order in server.cfg. The error means QBCore was nil at the moment your code ran, and the most common reason is that qb-core had not started yet. If your resource is ensured above qb-core, your code runs first, the export returns nothing, and you index nil. Move ensure qb-core above ensure my_resource, restart, and the object exists by the time your code reaches it. The code was fine. The order was wrong. This is why "is it a timing problem" is a better first question than "is my code broken."
Reading the colour, not just the words
Most console tools, txAdmin included, colour errors so you can triage at a glance before you read a single word. The pattern is consistent enough to lean on while you scan a fast-moving console.
Red is the one that demands action: the resource failed and something is broken now. Amber is a warning, often a deprecation notice or a missing-but-optional dependency; the resource still runs but the line is telling you about future pain. Green and plain white are normal life, including the started resource lines you want to see. When the console is scrolling, find the red first.
Common mistakes
These are the failure modes that send beginners in the wrong direction even after they have read the error. The error text was correct; the reaction to it was not.
| Symptom | Fix |
|---|---|
Could not load resource: failed to parse manifest | A directive in fxmanifest.lua is wrong. The usual culprit is singular vs plural: client_script takes ONE string, client_scripts takes a TABLE in curly braces. Fix the directive, then restart the resource. |
Failed to load script server/main.lua | The manifest names a file that does not exist at that path. Check for a typo or a renamed file. The path in the manifest must match the file on disk exactly, including the folder. |
attempt to index a nil value (global 'QBCore') | The framework object was nil when the code used it. Ensure qb-core starts BEFORE this resource in server.cfg, and guard with if QBCore then before you index it. |
attempt to call a nil value (global 'PlayerPedId') | You called a CLIENT native inside a server_script (or the reverse). PlayerPedId is client-only. Move the call to the correct side, matching the native's badge in the docs. |
it depends on oxmysql, which couldn't be started | A dependency is missing or starts too late. Add ensure oxmysql to server.cfg ABOVE the resource that needs it. After adding a new folder, run refresh first, then ensure. |
Unable to establish a connection to the database | This is config, not code. Check mysql_connection_string in server.cfg, confirm MariaDB is running, and confirm the database name exists. Percent-encode reserved chars in the password or use the key=value form. |
ER_NO_SUCH_TABLE / no such table | The connection works but the table was never created. Import the script's provided .sql file into your database once, then confirm the table appears in HeidiSQL. |
requires a different version of game data | sv_enforceGameBuild does not match the client or the assets. Set the correct build in server.cfg (startup only) to match what your DLC assets were made for. |
Could not load resource because it was already declared | The same folder name exists twice anywhere under resources. FiveM keys on folder name, not path. Delete or rename one copy so the name is unique, then refresh. |
I edited the file but the error is unchanged | Saving a file does nothing on a running server. Run restart on the resource after editing code or a manifest, and refresh then start after adding a whole new resource folder. |
What you can do now
- Read any FiveM error as an address: the resource in brackets, the file and line number, and the meaning at the end.
- Tell apart 'index a nil value' (reaching into an empty value) and 'call a nil value' (running an empty value as a function), and name the culprit from the parentheses.
- Diagnose a manifest failure by checking the singular vs plural directive and confirming every named file exists on disk.
- Fix dependency errors by setting load order in server.cfg with ensure, dependencies first, and using refresh after adding a new folder.
- Separate a database connection failure (mysql_connection_string config) from a 'no such table' error (an unimported .sql schema).
- Recognize an sv_enforceGameBuild mismatch and a duplicate-folder-name collision from their exact console text.