{"record":{"id":"79fb965be6a355ce","repo":"juicedata/juicefs","slug":"unable-to-create-engine-s","errorCode":null,"errorMessage":"unable to create engine: %s","messagePattern":"unable to create engine: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/meta/sql_mysql.go","lineNumber":67,"sourceCode":"\t}\n\treturn addr\n}\n\nfunc createMySQLEngine(dsn string) (*xorm.Engine, error) {\n\tcfg, err := mysql.ParseDSN(recoveryMysqlPwd(dsn))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif cfg.Params == nil {\n\t\tcfg.Params = make(map[string]string)\n\t}\n\n\tvar engine *xorm.Engine\n\tfor _, key := range []string{\"transaction_isolation\", \"tx_isolation\"} {\n\t\tcfg.Params[key] = \"'repeatable-read'\"\n\t\tengine, err = xorm.NewEngine(\"mysql\", cfg.FormatDSN())\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to create engine: %s\", err)\n\t\t}\n\n\t\tif err = engine.Ping(); err == nil {\n\t\t\treturn engine, nil\n\t\t}\n\n\t\t_ = engine.Close()\n\t\tdelete(cfg.Params, key)\n\n\t\tif !isUnknownTransactionIsolationErr(err, key) {\n\t\t\treturn nil, fmt.Errorf(\"ping database: %s\", err)\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"failed to set isolation level: %s\", err)\n}\n\nfunc isUnknownTransactionIsolationErr(err error, key string) bool {","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql_mysql.go#L49-L85","documentation":"JuiceFS builds a MySQL DSN (forcing transaction_isolation to repeatable-read) and calls xorm.NewEngine. If the driver cannot create an engine from the DSN (malformed DSN, bad params), this error wraps the underlying message. It is thrown before any network activity, so it almost always means the connection string itself is invalid.","triggerScenarios":"`juicefs format mysql://...` / `mount mysql://...` with a DSN whose FormatDSN() output the go-sql-driver rejects — e.g. malformed `dsn` param, unescaped special characters in password, or invalid parameter syntax.","commonSituations":"Special characters (!@#) in the MySQL password not URL-encoded in the JuiceFS meta URL; typos like `mysql://user:pass@tcp(host:3306)/db` with missing tcp() wrapper; unsupported query params passed through.","solutions":["Check the inner driver message in the error for the exact DSN problem and fix the meta URL accordingly.","URL-encode the password (and any special chars) in the meta URL, or pass the DSN with the password omitted and use env/my.cnf.","Verify the DSN follows go-sql-driver format: user:password@tcp(host:port)/dbname?params.","Test the same DSN with a small Go/CLI program using go-sql-driver to isolate whether it is a JuiceFS or driver issue."],"exampleFix":"// before (bad DSN: special chars unescaped)\njuicefs format \"mysql://root:p@ss!@tcp(1.2.3.4:3306)/jfs\" vol\n// after (URL-encode password: p@ss! -> p%40ss%21)\njuicefs format \"mysql://root:p%40ss%21@tcp(1.2.3.4:3306)/jfs\" vol","handlingStrategy":"validation","validationCode":"u, err := url.Parse(metaURL)\nif err != nil || !strings.HasPrefix(u.Scheme, \"mysql\") {\n    return fmt.Errorf(\"meta URL must be mysql://user:pass@tcp(host:port)/db\")\n}\nif pw, ok := u.User.Password(); ok && url.QueryEscape(pw) != pw {\n    return fmt.Errorf(\"password contains special characters: URL-encode it\")\n}","typeGuard":null,"tryCatchPattern":"if err := runMount(); err != nil && strings.Contains(err.Error(), \"unable to create engine\") {\n    log.Fatalf(\"invalid MySQL DSN: %v\", err)\n}","preventionTips":["URL-encode special characters in passwords","Validate the DSN with the mysql client or a minimal go-sql-driver test before mounting","Keep the DSN format user:pass@tcp(host:port)/db"],"tags":["mysql","database","connection-string","startup"],"backgroundTag":"invalid-url-format","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}