- Result code
- SQLITE_CANTOPEN (14); extended SQLITE_CANTOPEN_ISDIR (526) and SQLITE_CANTOPEN_FULLPATH (782)
- Product
- SQLite library
- Versions
- SQLite 3.x (examples run on 3.39.2; shell output from 3.50.6)
- Category
- Files & Permissions
- Last reviewed
- 24 October 2026
On this page
What it means
This error means SQLite could not open or create the file at the path it was given, usually because a folder in the path does not exist, the path is a folder, or the process lacks permission.
Opening a database normally creates the file if it is missing, but SQLite never creates folders. If any folder in the path does not exist, the path names a folder instead of a file, or the operating system refuses access, the open fails with SQLITE_CANTOPEN. Most drivers raise it when the connection is created (PDO and the PHP SQLite3 class throw from the constructor); others open lazily and report it on the first statement. A read-only open of a file that does not exist also fails this way, because a read-only connection may not create it. Relative paths are resolved against the process's current working directory, which for web servers, services, scheduled tasks and IDE run configurations is often not the folder you expect.
A file the process may not read fails the same way: we saw this on Windows after denying the account read access to a database file. The code also covers temporary files that SQLite cannot open (it uses them for VACUUM, some sorts and temporary tables, in the folder chosen as described in the temporary files documentation). The extended codes are SQLITE_CANTOPEN_ISDIR (526) when the path is a folder and SQLITE_CANTOPEN_FULLPATH (782) when the path cannot be turned into a full path; PHP's drivers do not expose them. If the file opens but cannot be written you get attempt to write a readonly database instead, and if it opens but is not SQLite, file is not a database.
Common causes
- A folder in the path does not exist: a data, storage or var folder that is not created on a fresh deployment or in a container image.
- A relative path resolved against a different working directory than the one you tested from.
- The path points to a folder rather than a file, for example a configuration value that is missing the file name.
- The process may not read the file or enter its folder (wrong owner or permissions, SELinux or AppArmor rules, a Windows ACL, or an Android app without access to that storage).
- The connection was opened read-only (or with a mode=ro URI) and the file does not exist.
- A typing mistake in the path or file name; note that with the default flags a mistyped name creates a new empty database instead, which later shows up as no such table.
Diagnose it
Read-only These statements only read the schema (sqlite_schema and read-only PRAGMA queries) or your own data. They do not change data, settings or the database file, so they are safe to run first.
Print the absolute path and the working directory
Log the exact path your code passes to SQLite and the current working directory of the process (getcwd() in PHP, os.getcwd() in Python), from the environment that fails rather than from your terminal. Then check that every folder in the path exists and that the last part is a file name, not a folder.
Check permissions as the user that runs the code
On Linux or macOS, namei -l /path/to/shop.db (or ls -ld on each folder) shows the owner and permissions of every folder on the way; the process needs execute permission on each folder and read permission on the file, plus write permission on the folder to create it. With SELinux, check ls -Z and the audit log. On Windows, check the security settings of the file and folder for the account that runs the service or application pool.
Confirm the path a working connection resolves to
Once a connection opens (for example from the sqlite3 shell with an absolute path), list its files. Compare the path with the one your failing code builds.
PRAGMA database_list; The absolute path of the main database and any attached databases. A blank file name means a temporary or in-memory database.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Create the folder before opening the database
Client or network sideSQLite creates the file, never the folder. Create it at deployment or start-up, for example mkdir -p /var/lib/myapp in a deploy script or Dockerfile, mkdir($dir, 0770, true) in PHP, os.makedirs(path, exist_ok=True) in Python.
Build an absolute path from a known location
Client or network sideDo not rely on the working directory. Build the path from the application's own folder or a configured data folder, for example __DIR__ . '/../var/shop.db' in PHP or Path(__file__).parent / 'shop.db' in Python, and make sure it ends with the file name.
Give the application user access to the folder and file
Changes permissionsThe user that runs the code needs execute permission on every folder in the path, read (and normally write) permission on the file, and write permission on its folder for the journal files. For example sudo chown -R www-data:www-data /var/lib/myapp. With SELinux, label the folder for your service (for example with semanage fcontext and restorecon) rather than disabling SELinux.
Allow creation, or check that the file exists, when opening read-only
Client or network sideA read-only connection cannot create a missing file. If the file should already be there, the path is wrong; if the program should create it, open it read-write first (the default flags in most drivers, mode=rwc in a URI filename).
Examples
A folder in the path does not exist
-- the connection is opened on data/shop.db, but the folder data/ does not exist
CREATE TABLE orders (id INTEGER PRIMARY KEY, total REAL);
unable to open database file
Reproduced on SQLite 3.39.2, 24 October 2026.
The path points to a folder
-- the connection is opened on the folder that should contain shop.db
SELECT COUNT(*) FROM sqlite_schema;
unable to open database file
Reproduced on SQLite 3.39.2, 24 October 2026.
Opening a file that does not exist with a read-only connection
-- the connection is opened read-only on shop.db, which does not exist yet
SELECT COUNT(*) FROM sqlite_schema;
unable to open database file
Reproduced on SQLite 3.39.2, 24 October 2026.
How to prevent it
Keep the database path in configuration as an absolute path, create its folder in the deployment script or container image, and check at start-up that the folder exists and is writable, so the problem shows up as a clear start-up message rather than an error on the first request.
When the application expects an existing database, open it with flags that do not create files (read-write without create, mode=rw in a URI) so a wrong path fails loudly here instead of silently creating an empty database. Keep the database outside the web root, owned by the application user.
Common questions
How do I fix "unable to open database file" in SQLite?
Print the absolute path your code opens and check that every folder in it exists, that it ends in a file name, and that the user running the code can read the file and write to its folder. SQLite creates missing files but not missing folders.
It works from my terminal but not from the web server or service. Why?
The service runs as a different user and usually from a different working directory. A relative path then points somewhere else, and that user may not have permission on the folder. Use an absolute path and give the service user access to the folder.
Does this error mean the database is corrupt?
No. SQLite could not open the file at all, so it never read its contents. Corruption is reported as "database disk image is malformed", and a file that is not SQLite as "file is not a database".
Learn more on CodeWithSQL
Official documentation
- SQLite result and error codes (SQLITE_CANTOPEN)
- Opening a database: sqlite3_open_v2 flags
- Temporary files used by SQLite
- URI filenames (mode=ro, mode=rw, mode=rwc)
Last technically reviewed 24 October 2026; examples and diagnostics run on SQLite 3.39.2 (PHP PDO_SQLITE) and the sqlite3 shell 3.50.6. Messages are the text the SQLite library itself returns (sqlite3_errmsg) for the versions shown.