{"record":{"id":"9a5121285e868b9f","repo":"juicedata/juicefs","slug":"parse-url-s-failed-s","errorCode":null,"errorMessage":"parse url %s failed: %s","messagePattern":"parse url (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql.go","lineNumber":472,"sourceCode":"\t\t}\n\t\tif !query.Has(\"_timeout\") && !query.Has(\"_busy_timeout\") {\n\t\t\tquery.Add(\"_timeout\", \"5000\")\n\t\t}\n\t}\n\n\tif encode := query.Encode(); encode != \"\" {\n\t\taddr = fmt.Sprintf(\"%s?%s\", baseUrl, encode)\n\t} else {\n\t\taddr = baseUrl\n\t}\n\n\tif driver == \"postgres\" {\n\t\taddr = driver + \"://\" + addr\n\t\tdriver = \"pgx\"\n\n\t\tparse, err := url.Parse(addr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"parse url %s failed: %s\", addr, err)\n\t\t}\n\t\tsearchPath = parse.Query().Get(\"search_path\")\n\t\tif searchPath != \"\" {\n\t\t\tif len(strings.Split(searchPath, \",\")) > 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"currently, only one schema is supported in search_path\")\n\t\t\t}\n\t\t}\n\t}\n\n\tif driver == \"sqlite3\" {\n\t\tDirBatchNum[\"db\"] = 4096 // SQLITE_MAX_VARIABLE_NUMBER limit\n\t}\n\n\tvar engine *xorm.Engine\n\tif creator, ok := engineCreator[driver]; ok {\n\t\tengine, err = creator(addr)\n\t} else {\n\t\tengine, err = xorm.NewEngine(driver, addr)","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L454-L490","documentation":"When the metadata driver is postgres, JuiceFS rewrites the address into a `postgres://...` URL, switches to the pgx driver, and parses it with net/url.Parse to extract search_path. If the address cannot be parsed as a URL (malformed scheme, invalid characters, bad host/port syntax), NewClient fails with this error before any database connection is attempted.","triggerScenarios":"`juicefs format`/`mount` with `--meta 'postgres://...'` where the host:port/credential portion is malformed so url.Parse fails, or an unescaped special character (space, raw `%`, unpaired `@`) appears in the credentials or query string.","commonSituations":"Passwords containing `@`, `:`, `/`, or `%` that are not URL-encoded; spaces in the URL; missing host; typos like double `://`; building the URL by string concatenation without escaping.","solutions":["URL-encode special characters in username/password (e.g. percent-encode `@` as `%40`).","Verify URL syntax: `postgres://user:password@host:port/dbname?param=value`.","Simplify to a minimal URL (`postgres://host/db`) and add parts back until the failure reproduces.","Move credentials out of the URL (PGPASSWORD, ~/.pgpass) if they contain awkward characters."],"exampleFix":"// before\n--meta 'postgres://user:p@ss@host:5432/db'\n// after\n--meta 'postgres://user:p%40ss@host:5432/db'","handlingStrategy":"validation","validationCode":"// validate the postgres URL before passing it to JuiceFS\nu, err := url.Parse(metaURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid postgres meta URL %q: %v\", metaURL, err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"parse url\") {\n        // re-encode credentials and retry once\n    }\n}","preventionTips":["Percent-encode every credential character (use url.UserPassword / url.QueryEscape in Go).","Never build metadata URLs by raw string concatenation.","Sanity-check the URL with url.Parse or an equivalent parser before deployment.","Avoid spaces and stray `%` characters in the URL."],"tags":["go","postgres","url-parsing","configuration"],"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-14T00:17:10.932Z"}