passbolt/passbolt_api · error · CakeException

A connection could not be established with the credentials…

Error message

A connection could not be established with the credentials provided. Please verify the settings.

What it means

DatabaseController::testConnection builds a config via DatabaseConfiguration::buildConfig, initializes the connection, and calls DatabaseConfiguration::testConnection(). If a connection cannot be made, it throws CakeException 'A connection could not be established with the credentials provided. Please verify the settings.' This is the WebInstaller's pre-flight DB connectivity check before writing config.

Solutions

  1. Verify host, port, database name, username and password by connecting manually (mysql -h <host> -u <user> -p or psql) with the exact values entered in the installer.
  2. In containerized setups (Docker/ddev) use the internal service hostname (e.g. 'db'), not 'localhost' or '127.0.0.1'.
  3. Confirm the database server is running and the port is reachable from the PHP container (nc -zv <host> <port>).
  4. Create the database/user beforehand and grant privileges: CREATE DATABASE passbolt; GRANT ALL ON passbolt.* TO 'passbolt'@'%';

Example fix

// before (form data)
host: localhost, port: 3306  // inside a container, localhost is the PHP container itself
// after
host: db, port: 3306, database: passbolt, username: passbolt, password: ****
Defensive patterns

Strategy: validation

Validate before calling

// probe connectivity with the exact settings before submitting the installer form
const net = require('net');
const s = net.connect({ host, port }, () => { console.log('reachable'); s.end(); });
s.on('error', (e) => { throw new Error('DB host unreachable: ' + e.message); });

Type guard

function isValidDbConfig(c) {
  return c && typeof c.host === 'string' && c.host.length > 0 &&
    Number.isInteger(Number(c.port)) && Number(c.port) > 0 &&
    typeof c.database === 'string' && c.database.length > 0 &&
    typeof c.username === 'string' && c.username.length > 0;
}

Try / catch

try {
  await post('/install/database', dbConfig);
} catch (e) {
  if (String(e.message).includes('A connection could not be established')) {
    // verify host/port/credentials out-of-band, then retry
  }
  throw e;
}

Prevention

When it happens

Trigger: The WebInstaller database step (indexPost -> testConnection) with an unreachable host/port, wrong database name, wrong username/password, or an unavailable database driver — testConnection() returns false.

Common situations: DB host entered as 'localhost' instead of the container service name (e.g. 'db' in ddev); MySQL/MariaDB not started; wrong port; DB user lacking privileges; Postgres vs MySQL confusion; firewall blocking the port.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/060d1c481812db0d. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/WebInstaller/src/Controller/DatabaseController.php:185

        return $nbAdmins > 0;
    }

    /**
     * Test the connection to the database
     *
     * @param array $data The database configuration to test
     * @throws \Cake\Core\Exception\CakeException A connection could not be established with the provided data
     * @return void
     */
    protected function testConnection(array $data): void
    {
        $config = DatabaseConfiguration::buildConfig($data);
        $this->webInstaller->setSettings('database', $config);
        $this->webInstaller->initDatabaseConnection();
        if (!DatabaseConfiguration::testConnection()) {
            $msg = __('A connection could not be established with the credentials provided.') . ' ';
            $msg .= __('Please verify the settings.');
            throw new CakeException($msg);
        }
    }

    /**
     * Validate data.
     *
     * @param array $data request data
     * @throws \Cake\Core\Exception\CakeException The data does not validate
     * @return array
     */
    protected function validateData(array $data): array
    {
        $form = new DatabaseConfigurationForm();
        $this->set('formExecuteResult', $form);
        if (!$form->execute($data)) {
            throw new CakeException(__('The data entered are not correct'));
        }
        /** @var array $data */

View on GitHub (pinned to 31c1bbc10f)