phacility/phabricator · error · AphrontInvalidCredentialsQueryException
1045
1045
Error message
#%d: %s
What it means
MySQL returned error 1045 'Access denied for user ...' (using password: YES/NO) during the handshake, which the connection layer translates to AphrontInvalidCredentialsQueryException. Unlike 1044/1142 (authorization of a specific statement), 1045 means the username/password/host combination itself was rejected. The account may also not exist for the host part MySQL resolved.
Source
Thrown at src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:362
// portable to parse the key out of the error and attach it to the
// exception.
throw new AphrontDuplicateKeyQueryException($message);
case 1044: // Access denied to database
case 1142: // Access denied to table
case 1143: // Access denied to column
case 1227: // Access denied (e.g., no SUPER for SHOW SLAVE STATUS).
// See T13622. Try to help users figure out that this is a GRANT
// problem.
$more = pht(
'This error usually indicates that you need to "GRANT" the '.
'MySQL user additional permissions. See "GRANT" in the MySQL '.
'manual for help.');
throw new AphrontAccessDeniedQueryException("{$message}\n\n{$more}");
case 1045: // Access denied (auth)
throw new AphrontInvalidCredentialsQueryException($message);
case 1146: // No such table
case 1049: // No such database
case 1054: // Unknown column "..." in field list
throw new AphrontSchemaQueryException($message);
}
// TODO: 1064 is syntax error, and quite terrible in production.
return null;
}
protected function throwConnectionException($errno, $error, $user, $host) {
$this->throwCommonException($errno, $error);
$message = pht(
'Attempt to connect to %s@%s failed with error #%d: %s.',
$user,
$host,View on GitHub (pinned to 5720a38cfe)
Solutions
- Prove the credentials outside Phabricator: mysql -h<host> -P<port> -u<user> -p from the same machine Phabricator runs on
- Fix the stored credentials, e.g. phabricator/bin/config set mysql.pass 'correct-password' (mind shell quoting of special characters)
- If the external test also fails, fix the MySQL account: CREATE USER ... IDENTIFIED BY ... for the exact host pattern the connection uses, or align the host you connect as
- For MySQL 8 auth-plugin mismatches, create the user with mysql_native_password or use a client/mysqlnd build that supports caching_sha2_password
Example fix
# before: stale password after a DB rotation phabricator/bin/config get mysql.pass # old value # after: update the stored credential, then verify phabricator/bin/config set mysql.pass 'new-p4ssw0rd!' phabricator/bin/storage probe
Defensive patterns
Strategy: validation
Validate before calling
// Fail fast at boot: verify the configured credentials before serving traffic.
$conn = new AphrontMySQLiDatabaseConnection();
$conn->setConfiguration($config);
try {
$conn->openConnection();
} catch (AphrontInvalidCredentialsQueryException $ex) {
throw new Exception(pht('Stored database credentials are invalid.'));
} Try / catch
try {
$conn = $dao->establishConnection('r');
} catch (AphrontInvalidCredentialsQueryException $ex) {
// Credential/config problem: page the operator; retrying is pointless.
} Prevention
- Keep database credentials in the Phabricator config (mysql.pass / cluster.databases), not in ad-hoc scripts
- After rotating the MySQL password, immediately update config and run phabricator/bin/storage probe
- Create MySQL accounts with a host pattern matching how the app actually connects (TCP vs localhost)
- On MySQL 8, prefer mysql_native_password or a client with caching_sha2_password support to avoid auth-plugin access-denied
When it happens
Trigger: mysql.user / mysql.pass (or cluster.databases credentials) in the connection configuration are wrong or stale; password contains characters that were mangled by shell or config quoting; the MySQL account exists as 'user'@'localhost' but the client connects over TCP as 'user'@'10.x.x.x' (or vice versa).
Common situations: Database password was rotated but Phabricator config was not updated; config copied between environments with different credentials; MySQL 8 default caching_sha2_password rejecting an older client, which surfaces as access denied; user dropped or recreated during maintenance.
Related errors
- Credential has invalid type "%s"!
- Credential "%s" is of unknown type "%s"!
- Attempt to connect to %s@%s failed with error #%d: %s.
- Configuration file is not properly formatted JSON. %s
- Configuration file has improper configuration keys at top le
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/46c357e2a081f4de.
Report an issue: GitHub.