juicedata/juicefs · critical
failed to set isolation level: %s
Error message
failed to set isolation level: %s
What it means
JuiceFS requires MySQL's isolation level to be settable to repeatable-read and probes with two system variable names (transaction_isolation for MySQL 5.7+/8.x, tx_isolation for older). If every probe's ping failed with 'unknown system variable' for all candidate keys, it gives up with this error, meaning the server is a dialect that supports neither variable or errors unexpectedly.
Source
Thrown at pkg/meta/sql_mysql.go:82
cfg.Params[key] = "'repeatable-read'"
engine, err = xorm.NewEngine("mysql", cfg.FormatDSN())
if err != nil {
return nil, fmt.Errorf("unable to create engine: %s", err)
}
if err = engine.Ping(); err == nil {
return engine, nil
}
_ = engine.Close()
delete(cfg.Params, key)
if !isUnknownTransactionIsolationErr(err, key) {
return nil, fmt.Errorf("ping database: %s", err)
}
}
return nil, fmt.Errorf("failed to set isolation level: %s", err)
}
func isUnknownTransactionIsolationErr(err error, key string) bool {
return err != nil && strings.Contains(strings.ToLower(err.Error()), fmt.Sprintf("unknown system variable '%s'", key))
}
func init() {
dupErrorCheckers = append(dupErrorCheckers, isMySQLDuplicateEntryErr)
engineCreator["mysql"] = createMySQLEngine
Register("mysql", newSQLMeta)
}
View on GitHub (pinned to c9a67b23e8)
Solutions
- Connect directly to a real MySQL (or MariaDB ≥5.7 with tx_isolation) server instead of through the proxy that hides system variables.
- Verify with mysql client: SHOW VARIABLES LIKE 'tx_isolation'; and SHOW VARIABLES LIKE 'transaction_isolation'; — one must exist.
- Check the wrapped error text: it shows the last 'unknown system variable' message; confirm which dialect the server actually is.
- If the proxy is required, configure it to pass through system-variable queries, or use a JuiceFS metadata engine that doesn't need this (redis/sqlite).
Example fix
// before (proxy strips system variables) juicefs mount "mysql://user:pass@tcp(proxy:6033)/jfs" /mnt/jfs // after (point at the real MySQL backend) juicefs mount "mysql://user:pass@tcp(mysql-primary:3306)/jfs" /mnt/jfs
Defensive patterns
Strategy: fallback
Validate before calling
out, _ := exec.Command("mysql", "-h", host, "-u", user, "-p"+pw, "-e", "SHOW VARIABLES LIKE 'tx_isolation'; SHOW VARIABLES LIKE 'transaction_isolation';").Output()
if len(out) == 0 { return fmt.Errorf("server exposes neither isolation variable; use a direct MySQL backend") } Try / catch
if err := mountVol(); err != nil && strings.Contains(err.Error(), "failed to set isolation level") {
log.Fatalf("server does not expose isolation variables — bypass proxy or switch engine: %v", err)
} Prevention
- Point JuiceFS at a real MySQL/MariaDB server, not a system-variable-stripping proxy
- Check SHOW VARIABLES for tx_isolation/transaction_isolation before onboarding a metadata host
- Fall back to redis/sqlite engines for restricted MySQL-compatible services
When it happens
Trigger: Connecting to a MySQL-compatible server that rejects both `transaction_isolation` and `tx_isolation` system variables — e.g. certain proxies (ProxySQL variants), MariaDB forks, or serverless MySQL gateways that strip system variables.
Common situations: Pointing JuiceFS at an aggressive MySQL proxy or managed service that doesn't expose isolation variables; a custom middleware rewriting the handshake; very old or heavily modified MySQL builds.
Related errors
- unable to create engine: %s
- ping database: %s
- unable to use data source %s: %s
- ping database: %s
- create table delegationToken: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/ed164961612dfbbe.
Report an issue: GitHub.