juicedata/juicefs · error

unescape %s: %s

Error message

unescape %s: %s

What it means

In `juicefs sync`, when a source/destination URI uses the `jfs` scheme, the volume name is carried in the URL host and may be percent-encoded. createSyncStorage calls url.PathUnescape on it; this error is returned when that unescaping fails, meaning the host component contains a malformed escape sequence such as `%zz` or a lone trailing `%`.

Source

Thrown at cmd/sync.go:420

		logger.Fatalf("Can't parse %q: %s", utils.RemovePassword(uri), utils.RemovePassword(err.Error()))
	}
	user := u.User
	var accessKey, secretKey string
	if user != nil {
		accessKey = user.Username()
		secretKey, _ = user.Password()
	}
	name := strings.ToLower(u.Scheme)

	var endpoint string
	if name == "file" {
		endpoint = u.Path
	} else if name == "hdfs" {
		endpoint = u.Host
	} else if name == "jfs" {
		endpoint, err = url.PathUnescape(u.Host)
		if err != nil {
			return nil, fmt.Errorf("unescape %s: %s", u.Host, err)
		}
		if os.Getenv(endpoint) != "" {
			conf.Env[endpoint] = os.Getenv(endpoint)
		}
	} else if name == "nfs" {
		endpoint = u.Host + u.Path
	} else if !conf.NoHTTPS && supportHTTPS(name, u.Host) {
		endpoint = "https://" + u.Host
	} else {
		endpoint = "http://" + u.Host
	}

	isS3PathTypeUrl := isS3PathType(u.Host)
	if name == "minio" || name == "s3" && isS3PathTypeUrl {
		// bucket name is part of path
		endpoint += u.Path
	}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Fix the URI so every '%' is followed by two hex digits, or remove unnecessary encoding entirely (e.g. `jfs://myvol` instead of `jfs://my%vol`)
  2. Percent-encode properly: `%` itself becomes `%25` (use python3 -c 'import urllib.parse;print(urllib.parse.quote(name))')
  3. If no special characters are in the volume name, use the raw name unencoded

Example fix

// before
jfs://vol%zz/subdir   # invalid escape
// after
jfs://vol%25zz/subdir  # '%25' is an encoded '%'
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(uri)
if err == nil && u.Scheme == "jfs" {
	if _, err := url.PathUnescape(u.Host); err != nil {
		return fmt.Errorf("bad jfs URI host %q: %w", u.Host, err)
	}
}

Type guard

null

Try / catch

store, err := createSyncStorage(...)
if err != nil && strings.HasPrefix(err.Error(), "unescape ") {
	// fix the URI or surface a config error to the user
}

Prevention

When it happens

Trigger: Calling doSync (or createSyncStorage) with a `jfs://` URI whose host contains an invalid percent-escape, e.g. `jfs://vol%2name/` or `jfs://my%vol/`. Any byte after '%' that is not two hex digits causes url.PathUnescape to fail.

Common situations: Manually percent-encoding a volume name containing special characters and getting the encoding wrong; scripts building URIs with printf/shell substitutions that mangle '%'; copying a URL that was encoded with a non-URL scheme.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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