Skip to main content
Test and optimize

Written lessons and reference material are currently in English.

On this page
Module A1 · Server setup from zero

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 seven errors every FiveM beginner hits. Each one has its exact console text, what it actually means, and the single fix that clears it.

You'll build
A reading habit and a lookup table. The exact console text of every error a beginner hits, what it means, and the one fix that clears it.
Time
~20 minutes
You need
A local FiveM server you can restart and a txAdmin Live Console you can read. If you do not have that yet, do the server setup lesson first, then come back.
You'll learn
How to read a traceback (resource, file, line). Then the seven errors that stop every beginner, with the exact text, the meaning, and the fix for each.
BEFORE YOU START

Read an error before you fix it

A FiveM error is not a wall of noise. It is a small structured report. It almost always names three things: which resource broke, which file the problem is in, and which line number to open. A resource is one self-contained folder of script and asset files that the server loads as a unit. Find those three things 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. The Live Console is the live server log inside the txAdmin dashboard. Read it top to bottom before you read the breakdown under it.

txAdmin · Live Console
code
[script:my_bank] Error loading script server/main.lua in resource my_bank:
server/main.lua:14: attempt to index a nil value (global 'QBCore')
stack traceback:
 server/main.lua:14: in main chunk
[script:my_bank] Failed to load script server/main.lua.

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:14 is the file and line. Open server/main.lua inside my_bank and go to line 14. 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 variable QBCore was nil when the code tried to use it. The thing in parentheses is the name of whatever was empty.
  • stack traceback is 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 seven you will meet first. 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 seven errors that stop beginners, in the order you tend to meet them. First the manifest problems that stop a resource loading, then runtime nil-value errors, then dependency, 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 manifest is fxmanifest.lua, the small file at the root of every resource that lists which scripts the resource runs. The resource never even started, because fxmanifest.lua is wrong or points at a file that is not there.

txAdmin · Live Console
code
Could not load resource my_bank: failed to parse manifest.
[script:my_bank] Failed to load script server/mian.lua.

Two root causes sit behind this message. The first is a manifest that does not parse. The manifest is a small Lua file, so it fails to parse when the Lua is malformed. The usual culprits are a missing closing quote on a filename, a missing } on a table, a misspelled directive name (for example sever_script instead of server_script), or a stray comma where the format does not expect one. Both the singular and the plural script directives accept either a single string or a table, so server_script 'a.lua' and server_scripts 'a.lua' are both valid; the plural is what you use when you want to list many files or a glob.

code
-- WRONG: missing the closing quote on the filename.
server_script 'server.lua

-- WRONG: table is missing its closing brace.
server_scripts {
 'a.lua',
 'b.lua'

-- WRONG: misspelled directive name (sever_script), so it is ignored or errors.
sever_script 'server.lua'

-- CORRECT: one file, either directive accepts a single string.
server_script 'server.lua'

-- CORRECT: many files or a glob, wrapped in a table.
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 a Failed to load script line (exact wording varies by build). 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.

txAdmin · Live Console
code
[script:my_bank] server/main.lua:14: attempt to index a nil value (global 'QBCore')

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.

This one matters when you install scripts that error, not because you will write this code yourself; you are reading it so you can recognize the cause in someone else's script. 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.

code
-- 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 cash = QBCore.Functions.GetPlayerData().money.cash -- 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.
-- Note: in QBCore, PlayerData.money is a TABLE ({ cash = 0, bank = 0 }),
-- so read the field you want, not .money itself.
if QBCore and QBCore.Functions then
 local Player = QBCore.Functions.GetPlayer(source)
 local cash = Player and Player.PlayerData.money.cash or 0
end

The line exports['qb-core']:GetCoreObject() above uses an export. An export is a function one resource publishes so other resources can call it. Here qb-core publishes GetCoreObject, and your resource calls it to get the framework object.

The 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. An event is a named message one script fires that other scripts listen for.

txAdmin · Live Console
code
[script:my_bank] server/main.lua:8: attempt to call a nil value (field 'DoThing')
[script:my_bank] server/main.lua:3: attempt to call a nil value (global 'PlayerPedId')

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. A native is a built-in game function FiveM exposes, like PlayerPedId. PlayerPedId is a client native, so calling it in a server_script gives you exactly the second line above.

code
-- 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() is nil if resourceA is not running. Ensure it in server.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.

txAdmin · Live Console
code
Couldn't start resource my_bank.
[a red line naming my_bank and the dependency it could not find; exact wording varies by build]

In a manifest you declare what must load first with the dependencies key. Note the key name and the table form.

code
fx_version 'cerulean'
game 'gta5'

server_script 'server.lua'

-- These resources must be started BEFORE this one.
dependencies {
 'oxmysql',
 'ox_lib'
}

The cerulean line above is the manifest format version. It is just the current label FiveM expects at the top of every fxmanifest.lua. The fix for the error 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.

code
# Load order is top to bottom. Dependencies first, dependents below them.
ensure oxmysql
ensure ox_lib
ensure qb-core
ensure my_bank

Two operational notes 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 standard MySQL library for FiveM. It reads its credentials from the mysql_connection_string convar in server.cfg. A convar is a configuration variable you set in server.cfg to change how the server or a resource behaves.

txAdmin · Live Console
code
[oxmysql] Unable to establish a connection to the database (0)
[oxmysql] ER_NO_SUCH_TABLE: Table 'es_db.bank_accounts' doesn't exist

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.

code
# 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"

If the connection fails, also confirm the database itself is up. Start the MariaDB Windows service in services.msc, or run Get-Service MariaDB* in PowerShell to check it. If something else already holds port 3306, stop the conflicting service.

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 or DBeaver), select your database, and run the script's .sql file against it.

Security note: mysql_connection_string stores your database password in plaintext inside server.cfg. Never commit server.cfg to a public repository, and never paste it into a Discord or a forum. And only import .sql files from scripts you trust, because a .sql file runs whatever SQL it contains against your database.

A quick way to confirm the import landed: list the tables and look for the one the error named.

HeidiSQL · es_db
Tables_in_es_db
users
bank_accounts
owned_vehicles
After importing the script's .sql file, the table named in the error now exists.

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.

FiveM Client · Connection
code
The server you are joining requires a different game version (3258).
[the client then prompts you to restart]

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 client shows this message and then prompts the player to restart so it can switch to the required build. The sneaky version of this bug has no error message at all. A DLC vehicle 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.

code
# 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.
# Examples: 2802, 3095, 3258. Newest supported build mid-2026 is 3751.
# Check the current supported list before you pick one.
sv_enforceGameBuild 3258

7. 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.

txAdmin · Live Console
code
Could not load resource my_bank because it was already declared.
[c-scripting-core] Creating script environments for my_bank failed.

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.

code
resources/
 [core]/
 my_bank/ <- one copy here
 [standalone]/
 my_bank/ <- a second copy with the SAME folder name -> collision

The 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.

Keep reading the full lesson

Sign in to start, then unlock every step of this lesson and the full FiveM School with a membership.

Still ahead in this lesson
  • How it works
  • Common mistakes
  • What you can do now
  • Try it yourself

The remainder of Reading and fixing common errors is available to FiveM School members.

Open the full lesson to mark it complete.