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

  1. 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.
  2. Check the meta URL for typos in host, port, database name, user, and password (URL-encode special characters in passwords).
  3. For sqlite3://, confirm the file's directory exists and is writable by the JuiceFS process.
  4. Check network reachability: ping/telnet the host:port, and verify firewall/security-group rules allow the DB port.
  5. Inspect the wrapped driver error in the message for specifics (e.g. 'connection refused', 'Access denied', 'unknown database') and fix accordingly.
  6. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/5991afda97c10eee. Report an issue: GitHub.