{"record":{"id":"5991afda97c10eee","repo":"juicedata/juicefs","slug":"ping-database-s","errorCode":null,"errorMessage":"ping database: %s","messagePattern":"ping database: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/meta/sql.go","lineNumber":510,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to use data source %s: %s\", driver, err)\n\t}\n\n\tswitch logger.Level { // make xorm less verbose\n\tcase logrus.TraceLevel:\n\t\tengine.SetLogLevel(log.LOG_DEBUG)\n\tcase logrus.DebugLevel:\n\t\tengine.SetLogLevel(log.LOG_INFO)\n\tcase logrus.InfoLevel, logrus.WarnLevel:\n\t\tengine.SetLogLevel(log.LOG_WARNING)\n\tcase logrus.ErrorLevel:\n\t\tengine.SetLogLevel(log.LOG_ERR)\n\tdefault:\n\t\tengine.SetLogLevel(log.LOG_OFF)\n\t}\n\tstart := time.Now()\n\tif err = engine.Ping(); err != nil {\n\t\treturn nil, fmt.Errorf(\"ping database: %s\", err)\n\t}\n\tif time.Since(start) > time.Millisecond*5 {\n\t\tlogger.Warnf(\"The latency to database is too high: %s\", time.Since(start))\n\t}\n\tif searchPath != \"\" {\n\t\tengine.SetSchema(searchPath)\n\t}\n\tif vOpenConns > 0 {\n\t\tengine.DB().SetMaxOpenConns(vOpenConns)\n\t}\n\tif vLifeTime > 0 {\n\t\tengine.DB().SetConnMaxLifetime(time.Second * time.Duration(vLifeTime))\n\t}\n\tengine.DB().SetMaxIdleConns(vIdleConns)\n\tengine.DB().SetConnMaxIdleTime(time.Second * time.Duration(vIdleTime))\n\tengine.SetTableMapper(prefixMapper{mapper: engine.GetTableMapper(), prefix: tablePrefix})\n\tm := &dbMeta{\n\t\tbaseMeta:    newBaseMeta(engine.DataSourceName(), conf),","sourceCodeStart":492,"sourceCodeEnd":528,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L492-L528","documentation":"During SQL metadata engine initialization (newSQLMeta in pkg/meta/sql.go), JuiceFS opens a database connection via xorm and immediately calls engine.Ping() to verify connectivity. If the ping fails, the engine cannot reach the database and initialization aborts with \"ping database: %s\" wrapping the underlying driver error. This is a startup-time connectivity check, not a query failure.","triggerScenarios":"Running `juicefs format`, `juicefs mount`, or any command using a SQL metadata URL (mysql://, postgres://, sqlite3://) when the DB server is unreachable: server down, wrong host/port, bad credentials, database doesn't exist, socket file missing, or TLS misconfiguration.","commonSituations":"Database container not started or still initializing; wrong hostname/port in the meta URL; MySQL/PostgreSQL user lacks connect rights; sqlite3 file path in a non-writable/nonexistent directory; firewall or security group blocking the DB port; database dropped after a previous mount.","solutions":["Verify the database server is running and reachable: `mysql -h <host> -P <port> -u <user> -p` or `psql <url>` with the same credentials as the meta URL.","Check the meta URL for typos in host, port, database name, user, and password (URL-encode special characters in passwords).","For sqlite3://, confirm the file's directory exists and is writable by the JuiceFS process.","Check network reachability: ping/telnet the host:port, and verify firewall/security-group rules allow the DB port.","Inspect the wrapped driver error in the message for specifics (e.g. 'connection refused', 'Access denied', 'unknown database') and fix accordingly.","If using MySQL/PostgreSQL, grant the user privileges: `GRANT ALL ON juicefs.* TO 'user'@'host';`"],"exampleFix":"// before (server unreachable)\njuicefs format mysql://wronghost:3306/jfs myvol\n// error: ping database: dial tcp: lookup wronghost: no such host\n\n// after (correct reachable host)\njuicefs format mysql://user:pass@tcp(127.0.0.1:3306)/jfs myvol","handlingStrategy":"retry","validationCode":"// Before mounting, verify the SQL metadata endpoint is reachable\naddr := \"mysql://user:pass@tcp(127.0.0.1:3306)/jfs\"\nif err := pingDatabase(addr); err != nil {\n    log.Fatalf(\"metadata DB unreachable, fix config before starting: %v\", err)\n}\n\nfunc pingDatabase(addr string) error {\n    u, _ := url.Parse(addr)\n    // crude preflight: dial host:port\n    host := u.Hostname(); port := u.Port()\n    if port == \"\" { port = \"3306\" }\n    conn, err := net.DialTimeout(\"tcp\", net.JoinHostPort(host, port), 3*time.Second)\n    if err != nil { return err }\n    conn.Close()\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Wrap the mount/format call and distinguish connectivity from other errors\nif err := runJuiceFS(); err != nil {\n    if strings.Contains(err.Error(), \"ping database\") {\n        // connectivity problem: back off and retry with limit\n        for i := 0; i < 5; i++ {\n            time.Sleep(time.Duration(1<<i) * time.Second)\n            if retryErr := runJuiceFS(); retryErr == nil { return }\n        }\n        log.Fatalf(\"database unreachable after retries: %v\", err)\n    }\n    return err\n}","preventionTips":["Run a health check (mysql ping / pg_isready) on the DB before starting JuiceFS in scripts and systemd units.","Keep credentials and host in one reviewed meta URL; URL-encode passwords with special characters.","For sqlite3, place the DB file on a persistent, writable volume and check the directory exists.","Use connection/health monitoring so DB outages are alerted before clients fail.","Configure restart-with-backoff (systemd Restart=on-failure) for transient DB restarts."],"tags":["database","startup","connectivity","metadata-engine"],"backgroundTag":"connection-refused","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}