CodeIgniter Query Builder Returns Empty Results or Connection Errors: A Diagnostic Guide
CodeIgniter query builder returning empty results or connection errors despite correct SQL? Diagnose credentials, PHP extensions, driver mismatches, and environment config step by step.
09 Jan 2026, 13:19 UTC

Your SQL is correct — you ran it in a client and it returned rows — but CodeIgniter's query builder gives you an empty result set, or worse, a white page with "Unable to connect to your database server." The framework sits between your code and MySQL, so the fault is almost never the SQL itself. It is the configuration, the driver, or how the database library is being loaded. This guide walks through the checks in the order most likely to find the problem fastest.
Assumptions: CodeIgniter 3.x with the classic application/config/database.php config and the $this->db query builder. CodeIgniter 4 uses .env and app/Config/Database.php instead — the diagnostic logic is the same, but file paths differ.
Recognize the condition
Three symptoms share the same root causes:
- Empty result set:
$this->db->get('users')->result()returns[]while the same query in phpMyAdmin returns rows. - Connection error: "Unable to connect to your database server using the provided settings" on page load.
- Silent failure: the page renders but data sections are blank, with errors only visible in
application/logs/.
Cause and diagnostic table
| Symptom | Likely cause | Quick check |
|---|---|---|
| Connection error on every page | Wrong credentials or hostname in database.php | Test the same credentials with a standalone PHP script |
| Connection error after server migration | Missing PHP extension (mysqli, pdo_mysql) | php -m | grep -i mysql |
| Driver error message | dbdriver set to a driver that isn't installed | Compare $db['default']['dbdriver'] against loaded extensions |
| Empty results, no error | Connected to the wrong database (e.g., staging vs production) | Run SELECT DATABASE() through the query builder |
| Intermittent failures under load | Persistent connections (pconnect) exhausting MySQL's connection pool | Check max_connections usage on the MySQL server |
| Works in one environment, fails in another | Environment-specific config not loaded, or cached config | Confirm which ENVIRONMENT value is active |
Ordered checks
1. Verify the credentials outside the framework
Before touching CodeIgniter, prove the credentials work. Create a temporary file in your web root (delete it afterward — it exposes a connection attempt to anyone who guesses the URL):
<?php
// dbtest.php — temporary, delete after use
$m = new mysqli('localhost', 'ci_user', 'secret', 'ci_app');
if ($m->connect_error) {
die('Connect failed: ' . $m->connect_error);
}
echo 'Connected. Server: ' . $m->server_info;
Run it as the web server user (via browser or sudo -u www-data php dbtest.php from the CLI). If this fails, the problem is MySQL or the credentials — CodeIgniter is not involved yet. Fix this layer first.
2. Confirm the PHP extension is loaded
CodeIgniter's mysqli driver needs the mysqli extension; pdo needs pdo_mysql. From the server CLI:
php -m | grep -iE 'mysqli|pdo_mysql'
Note that CLI and web SAPI configurations can differ — a module enabled for php-cli may be missing for php-fpm or Apache. Check the web side with a phpinfo() page if CLI looks fine but the site still fails. Install the missing package (e.g., apt install php-mysql on Debian/Ubuntu) and restart the web server or php-fpm.
3. Inspect database.php
Open application/config/database.php and check the active group (usually default):
$db['default'] = array(
'hostname' => 'localhost',
'username' => 'ci_user',
'password' => 'secret',
'database' => 'ci_app',
'dbdriver' => 'mysqli', // must match an installed extension
'pconnect' => FALSE, // set FALSE while diagnosing
'db_debug' => (ENVIRONMENT !== 'production'),
);
Common traps: hostname set to localhost when MySQL listens only on a TCP address (try 127.0.0.1, which forces TCP instead of a Unix socket), a stale environment override in application/config/development/database.php shadowing your edits, and dbdriver left as mysql — the old extension removed in PHP 7.
4. Check how the library is loaded
If the connection is fine but queries return nothing, confirm the database library is actually loaded and you are querying the group you think you are. In a controller:
$this->load->database(); // or autoload it
$query = $this->db->query('SELECT DATABASE() AS db');
var_dump($query->row()->db); // which database are you really on?
If this prints an unexpected database name, you are editing config for the wrong group or environment. If it prints the right name, the issue is in your query logic — enable the profiler in the controller with $this->output->enable_profiler(TRUE); to see the exact SQL the query builder generated, then compare it against what you ran manually.
5. Read the logs
Set $config['log_threshold'] = 1; in application/config/config.php (temporarily) and check application/logs/log-YYYY-MM-DD.php. Database errors there include the failing query and the MySQL error message — far more specific than the generic connection page.
Fixes tied to findings
- Bad credentials: correct them in the environment-specific config file, not the shared one, so production and staging don't collide. Changing production credentials can break other applications using the same database user — coordinate before rotating passwords.
- Missing extension: install it and restart the web SAPI; recheck with
phpinfo()from the web context. - Wrong driver: set
dbdrivertomysqli(orpdowith a validdsn/subdriver) matching what is installed. - Connection exhaustion: set
'pconnect' => FALSE. Be aware this adds per-request connection overhead; under heavy traffic, revisit MySQL'smax_connectionsand pool sizing rather than re-enabling persistent connections blindly. - Wrong database: fix the
databasevalue or pass the correct group:$this->load->database('other_group');.
Verify the fix
Add a throwaway controller method that exercises the real path:
public function dbcheck() {
$this->load->database();
$rows = $this->db->limit(5)->get('users')->result();
echo count($rows) . ' rows returned';
}
Load it in a browser, confirm the expected row count, then enable the profiler once to confirm no database errors appear. Remove the method when done. Also re-check the log file for the current date — a clean page with fresh errors in the log means the problem is only partially fixed.
When to escalate
Stop editing CodeIgniter config and look lower in the stack when: the standalone connection test fails with correct credentials (check MySQL's error.log, socket file permissions, and whether skip-networking is set); PHP logs show fatal errors unrelated to the database (an out-of-memory crash can masquerade as a DB failure); or the MySQL server itself is down or refusing connections — at that point it is a hosting or DBA issue, not a framework one. On shared hosting, open a ticket with the exact error from your standalone test; it gives support something concrete to act on.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.