juicedata/juicefs · critical
ping database: %s
Error message
ping database: %s
What it means
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.
Source
Thrown at pkg/meta/sql.go:510
if err != nil {
return nil, fmt.Errorf("unable to use data source %s: %s", driver, err)
}
switch logger.Level { // make xorm less verbose
case logrus.TraceLevel:
engine.SetLogLevel(log.LOG_DEBUG)
case logrus.DebugLevel:
engine.SetLogLevel(log.LOG_INFO)
case logrus.InfoLevel, logrus.WarnLevel:
engine.SetLogLevel(log.LOG_WARNING)
case logrus.ErrorLevel:
engine.SetLogLevel(log.LOG_ERR)
default:
engine.SetLogLevel(log.LOG_OFF)
}
start := time.Now()
if err = engine.Ping(); err != nil {
return nil, fmt.Errorf("ping database: %s", err)
}
if time.Since(start) > time.Millisecond*5 {
logger.Warnf("The latency to database is too high: %s", time.Since(start))
}
if searchPath != "" {
engine.SetSchema(searchPath)
}
if vOpenConns > 0 {
engine.DB().SetMaxOpenConns(vOpenConns)
}
if vLifeTime > 0 {
engine.DB().SetConnMaxLifetime(time.Second * time.Duration(vLifeTime))
}
engine.DB().SetMaxIdleConns(vIdleConns)
engine.DB().SetConnMaxIdleTime(time.Second * time.Duration(vIdleTime))
engine.SetTableMapper(prefixMapper{mapper: engine.GetTableMapper(), prefix: tablePrefix})
m := &dbMeta{
baseMeta: newBaseMeta(engine.DataSourceName(), conf),View on GitHub (pinned to c9a67b23e8)
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';`
Example fix
// before (server unreachable) juicefs format mysql://wronghost:3306/jfs myvol // error: ping database: dial tcp: lookup wronghost: no such host // after (correct reachable host) juicefs format mysql://user:pass@tcp(127.0.0.1:3306)/jfs myvol
Defensive patterns
Strategy: retry
Validate before calling
// Before mounting, verify the SQL metadata endpoint is reachable
addr := "mysql://user:pass@tcp(127.0.0.1:3306)/jfs"
if err := pingDatabase(addr); err != nil {
log.Fatalf("metadata DB unreachable, fix config before starting: %v", err)
}
func pingDatabase(addr string) error {
u, _ := url.Parse(addr)
// crude preflight: dial host:port
host := u.Hostname(); port := u.Port()
if port == "" { port = "3306" }
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), 3*time.Second)
if err != nil { return err }
conn.Close()
return nil
} Try / catch
// Wrap the mount/format call and distinguish connectivity from other errors
if err := runJuiceFS(); err != nil {
if strings.Contains(err.Error(), "ping database") {
// connectivity problem: back off and retry with limit
for i := 0; i < 5; i++ {
time.Sleep(time.Duration(1<<i) * time.Second)
if retryErr := runJuiceFS(); retryErr == nil { return }
}
log.Fatalf("database unreachable after retries: %v", err)
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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
- ping database: %s
- unable to create engine: %s
- failed to set isolation level: %s
- load setting: %s
- object storage: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/5991afda97c10eee.
Report an issue: GitHub.