Skip to content

[Bug] root@localhost account not created on MariaDB 11.4 + Ubuntu 24.04 (arm64) — site creation fails silently #748

@richardn-tw

Description

@richardn-tw

Environment

Item Version
CloudPanel v2.5.3
CloudPanel CLI 6.0.8
MariaDB 11.4.10
OS Ubuntu 24.04 (Noble)
Architecture arm64

Description

After a clean CloudPanel installation with DB_ENGINE=MARIADB_11.4, the installation completes without errors. However, creating the first website fails with a database error.

This is a silent failure — the installer reports success, but the MariaDB root@localhost account is never created. CloudPanel connects to MariaDB via localhost (Unix socket path), so the missing account causes every site creation to fail.

Root Cause

After installation, mysql.global_priv only contains root@127.0.0.1. The root@localhost account (required for socket-based connections) is absent:

SELECT User, Host FROM mysql.global_priv WHERE User='root';
-- Result:
-- root | 127.0.0.1   ← only this exists
-- root | localhost   ← MISSING

MariaDB 11.4 changed the default initialization behavior for root@localhost. The CloudPanel install script appears to rely on the old behavior where root@localhost was created automatically, and only sets up root@127.0.0.1 explicitly.

Note: this issue is related to but distinct from #574 (install script crash) and #616 (arm64 install failure) — in this case the installation appears to succeed, making the bug harder to diagnose.

Steps to Reproduce

  1. Fresh Ubuntu 24.04 arm64 server
  2. Run CloudPanel installer with MariaDB 11.4:
    DB_ENGINE=MARIADB_11.4 bash install.sh
  3. Installation completes successfully
  4. Log in to CloudPanel and attempt to create a new website
  5. Site creation fails with a database error

Workaround

Manually create the missing root@localhost account after installation:

# Step 1: enter skip-grant-tables mode
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl restart mariadb

# Step 2: get the CloudPanel root password
DB_PASS=$(sudo -u clp php -r "
require '/home/clp/htdocs/app/files/vendor/autoload.php';
use Defuse\\Crypto\\Crypto;
\$env = parse_ini_file('/home/clp/htdocs/app/.env');
\$enc = shell_exec('sqlite3 /home/clp/htdocs/app/data/db.sq3 \"SELECT password FROM database_server LIMIT 1\"\');
echo Crypto::decryptWithPassword(trim(\$enc), \$env['APP_SECRET']) . PHP_EOL;
" 2>/dev/null)

# Step 3: insert root@localhost (do NOT run FLUSH PRIVILEGES)
sudo mariadb -u root -e "
INSERT IGNORE INTO mysql.global_priv (User, Host, priv) VALUES (
  'root', 'localhost',
  json_set(
    '{\"access\":1099511627775,\"version_id\":110410,\"plugin\":\"mysql_native_password\",\"password_last_changed\":$(date +%s)}',
    '\$.authentication_string', PASSWORD('$DB_PASS')
  )
);
"

# Step 4: restore normal mode
sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl restart mariadb

Expected Behavior

Installation on MariaDB 11.4 + Ubuntu 24.04 should create both root@127.0.0.1 and root@localhost with the same password, so that CloudPanel can connect via Unix socket immediately after install.

Additional Notes

  • MariaDB 11.4: mysql.user is a VIEW and cannot be updated directly; mysql.global_priv must be used instead
  • Running FLUSH PRIVILEGES inside a skip-grant-tables session will immediately reload the grant tables and revoke the passwordless access, so it must be avoided during the workaround

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions