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.
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.
Linux defaults to case-sensitive table/database names, macOS/Windows to insensitive. A dump restored with different settings turns every referenced name into '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.
mysql -h <host> -P <port> -u <user> -p -e 'SHOW DATABASES;'
mysql -e 'CREATE DATABASE <name> CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;'
mysql -e "GRANT ALL PRIVILEGES ON <name>.* TO '<appuser>'@'%'; FLUSH PRIVILEGES;"
mysql -e "SHOW VARIABLES LIKE 'lower_case_table_names';"
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.
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).
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.
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.