MySQL "Unknown Database" — Names, Grants, and Case Sensitivity

The server doesn't know the database you named: it doesn't exist, or the lowercase/UTF8 quirks of identifiers bit you. Three checks and it's obvious which.

What you'll see

Root causes

Database truly absent on THIS server/port

Different instance than you think: SHOW DATABASES; on the exact host:port the app uses. Common after a port change or a stale my.cnf [client] config.

lower_case_table_names mismatch between environments

Linux defaults to case-sensitive table/database names, macOS/Windows to insensitive. A dump restored with different settings turns every referenced name into 'unknown'.

Name vs grant confusion (access denied vs unknown)

'Unknown database' can also surface for users with no privileges on it (client libs report it that way). CREATE USER/GRANT on the db clarifies.

Fix it

  1. List what this server actually has
    mysql -h <host> -P <port> -u <user> -p -e 'SHOW DATABASES;'
  2. Create the database if it's genuinely missing
    mysql -e 'CREATE DATABASE <name> CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;'
  3. Grant the app user access (fixes the permission-flavored variant)
    mysql -e "GRANT ALL PRIVILEGES ON <name>.* TO '<appuser>'@'%'; FLUSH PRIVILEGES;"
  4. Case sensitivity: verify the setting matches your other environments
    mysql -e "SHOW VARIABLES LIKE 'lower_case_table_names';"

Field note

lower_case_table_names MUST be set before data import on Linux if your names mix case — it cannot be changed after tables exist. Connection strings and my.cnf both carry host/port: confirm the app isn't reading a stale [client] block.

Common questions

The database exists — I created it last week!

Confirm the server and port the failing client uses: SHOW DATABASES via the same connection string. Most 'it exists' cases are two different instances, or the case-sensitivity difference between dev (mac/Win) and prod (Linux).

Why does the same dump import fine locally but break in production?

lower_case_table_names differs: local (1, insensitive) accepted MyTable and mytable as one; Linux (0, sensitive) sees two different names and the app's queries miss. Align the variable before import.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.