{"record":{"id":"ea17a5378a79c952","repo":"nocobase/nocobase","slug":"unable-to-connect-to-the-database","errorCode":null,"errorMessage":"Unable to connect to the database","messagePattern":"Unable to connect to the database","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/core/database/src/database.ts","lineNumber":887,"sourceCode":"        });\n        const nextDelay = startingDelay * Math.pow(timeMultiple, attemptNumber - 1);\n        attemptNumber++;\n        if (attemptNumber < (retry as number)) {\n          this.logger.warn(`will retry in ${nextDelay}ms...`, { method: 'auth' });\n        }\n        throw error; // Re-throw the error so that backoff can catch and handle it\n      }\n    };\n\n    try {\n      await backOff(authenticate, {\n        numOfAttempts: retry as number,\n        startingDelay: startingDelay,\n        timeMultiple: timeMultiple,\n        maxDelay: 30 * 1000,\n      });\n    } catch (error) {\n      throw new Error(`Unable to connect to the database`, { cause: error });\n    }\n  }\n\n  /**\n   * @internal\n   */\n  async checkVersion() {\n    return process.env.DB_SKIP_VERSION_CHECK === 'on' || (await checkDatabaseVersion(this));\n  }\n\n  /**\n   * @internal\n   */\n  async prepare() {\n    if (this.isMySQLCompatibleDialect()) {\n      const result = await this.sequelize.query(`SHOW VARIABLES LIKE 'lower_case_table_names'`, { plain: true });\n\n      if (result?.Value === '1' && !this.options.underscored) {","sourceCodeStart":869,"sourceCodeEnd":905,"githubUrl":"https://github.com/nocobase/nocobase/blob/fa42722fefe44265490dff2c27d79e2882bce4fa/packages/core/database/src/database.ts#L869-L905","documentation":"Database.auth() attempts an initial connection using async-retry; after all retry attempts (numOfAttempts) are exhausted, the underlying driver error is wrapped and rethrown as 'Unable to connect to the database'. The real cause is attached as error.cause — inspect it for credentials, host, port, or server-down details.","triggerScenarios":"db.auth() with wrong DB_HOST/DB_PORT; wrong DB_USER/DB_PASSWORD; database server not running; firewall/network unreachable; database with the given name does not exist; retry count exhausted on a slow server.","commonSituations":"Docker container starting before the DB container is ready; wrong credentials after rotating passwords; MySQL/Postgres bound to localhost only while the app runs in a container; typo'd connection string.","solutions":["Read error.cause (or error.original) for the actual driver-level reason","Verify DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_DATABASE values by connecting with psql/mysql CLI or a GUI client","Ensure the database server is running and reachable from the app host (docker-compose healthcheck / depends_on with condition: service_healthy)","If the DB starts slowly, increase retry attempts or starting delay passed to auth()"],"exampleFix":"// before\nawait db.auth({ retryAttempts: 1 });\n// after\ntry {\n  await db.auth({ retryAttempts: 10, retryDelay: 3000 });\n} catch (e) {\n  console.error('DB connect failed:', e.cause); // real driver error\n  throw e;\n}","handlingStrategy":"retry","validationCode":"// preflight: quick TCP check before auth\nimport net from 'net';\nconst ok = await new Promise(res => { const s = net.connect(port, host); s.once('connect', () => { s.end(); res(true); }); s.once('error', () => res(false)); });\nif (!ok) throw new Error(`DB ${host}:${port} unreachable`);","typeGuard":null,"tryCatchPattern":"try {\n  await db.auth({ retryAttempts: 10, retryDelay: 3000 });\n} catch (e) {\n  console.error('DB connection failed:', e.cause ?? e); // surface driver-level cause\n  process.exit(1);\n}","preventionTips":["Use docker-compose healthchecks / depends_on condition: service_healthy","Store credentials in env vars and test them with a CLI client during CI","Enable generous retry settings in containerized environments","Alert on error.cause rather than the generic wrapper message"],"tags":["database","connection","network","retry"],"backgroundTag":"database-connection-failed","analyzedSha":"fa42722fefe44265490dff2c27d79e2882bce4fa","analyzedAt":"2026-09-01T00:54:31.202Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}