juicedata/juicefs · error

url parse %s: %s

Error message

url parse %s: %s

What it means

newRedisMeta (pkg/meta/redis.go:111-115) builds the URI as `driver + "://" + addr` (e.g. `redis://host:6379`) and parses it with net/url.Parse before handing it to the redis client. If the resulting string is not a valid URL, the client cannot be constructed and this error is returned wrapping the parse failure. It almost always means the address portion contained characters that are illegal in a URL or an empty/malformed host.

Source

Thrown at pkg/meta/redis.go:114

	shaResolve string // The SHA returned by Redis for the loaded `scriptResolve`
	cache      *redisCache
}

var _ Meta = (*redisMeta)(nil)
var _ engine = (*redisMeta)(nil)

func init() {
	Register("redis", newRedisMeta)
	Register("rediss", newRedisMeta)
	Register("unix", newRedisMeta)
}

// newRedisMeta return a meta store using Redis.
func newRedisMeta(driver, addr string, conf *Config) (Meta, error) {
	uri := driver + "://" + addr
	u, err := url.Parse(uri)
	if err != nil {
		return nil, fmt.Errorf("url parse %s: %s", uri, err)
	}
	values := u.Query()
	query := queryMap{&values}
	minRetryBackoff := query.duration("min-retry-backoff", "min_retry_backoff", time.Millisecond*20)
	maxRetryBackoff := query.duration("max-retry-backoff", "max_retry_backoff", time.Second*10)
	readTimeout := query.duration("read-timeout", "read_timeout", time.Second*30)
	writeTimeout := query.duration("write-timeout", "write_timeout", time.Second*5)
	routeRead := query.pop("route-read")
	skipVerify := query.pop("insecure-skip-verify")
	certFile := query.pop("tls-cert-file")
	keyFile := query.pop("tls-key-file")
	caCertFile := query.pop("tls-ca-cert-file")
	tlsServerName := query.pop("tls-server-name")

	// Client-side caching options
	clientCacheStr := query.pop("client-cache")
	clientCache := clientCacheStr != "false" && clientCacheStr != ""
	clientCacheSize := query.getInt("client-cache-size", "client_cache_size", 12800)

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Print the exact `driver://addr` string from the error and fix illegal characters (spaces, quotes, stray brackets).
  2. For IPv6, wrap the host in brackets: `redis://[::1]:6379`.
  3. Percent-encode special characters in embedded username/password (e.g. `redis://user:p%40ss@host:6379`).
  4. Ensure the env var/config actually contains the address (an empty addr yields `redis://` which may fail downstream checks).

Example fix

// before
metaUrl := "redis://" + os.Getenv("REDIS_HOST") // REDIS_HOST=" 127.0.0.1:6379 " -> url parse fails
// after
metaUrl := "redis://" + strings.TrimSpace(os.Getenv("REDIS_HOST"))
Defensive patterns

Strategy: validation

Validate before calling

// validate the meta URL before invoking JuiceFS
u, err := url.Parse(metaURL)
if err != nil { return fmt.Errorf("invalid meta URL %q: %w", metaURL, err) }
if u.Host == "" { return fmt.Errorf("meta URL %q has no host", metaURL) }

Try / catch

if err != nil && strings.Contains(err.Error(), "url parse ") {
	return fmt.Errorf("check REDIS address for illegal characters/brackets: %w", err)
}

Prevention

When it happens

Trigger: Calling `juicefs mount redis://...` / `NewMeta` with a redis address containing spaces, stray quotes, unmatched brackets (e.g. `redis://[::1`), control characters, or an empty addr; also passing a full URL with an illegal scheme part into addr.

Common situations: Copy-pasted address with trailing whitespace or quotes from config/env; IPv6 literal missing brackets; credentials with special characters not percent-encoded in the URL; shell variable expansion leaving the address empty.

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/938fa8fd14269154. Report an issue: GitHub.