juicedata/juicefs · error

Invalid endpoint: %v, error: %v

Error message

Invalid endpoint: %v, error: %v

What it means

newGS validates the GCS endpoint by parsing it as a URL; if url.ParseRequestURI fails it returns this error. It means the endpoint string supplied to the gs object storage backend is not a parseable absolute URI. The library auto-prefixes `gs://` when no scheme is present, so even bare hostnames must otherwise be well-formed.

Source

Thrown at pkg/object/gs.go:203

		}
	}
	if delimiter != "" {
		sort.Slice(objs, func(i, j int) bool { return objs[i].Key() < objs[j].Key() })
	}
	return objs, nextPageToken != "", nextPageToken, nil
}

// Restore GCS does not support restoring objects to a temporary readable state.
func (g *gs) Restore(ctx context.Context, key string, days int32) error {
	return notSupported
}
func newGS(endpoint, accessKey, secretKey, token string) (ObjectStorage, error) {
	if !strings.Contains(endpoint, "://") {
		endpoint = fmt.Sprintf("gs://%s", endpoint)
	}
	uri, err := url.ParseRequestURI(endpoint)
	if err != nil {
		return nil, errors.Errorf("Invalid endpoint: %v, error: %v", endpoint, err)
	}
	hostParts := strings.Split(uri.Host, ".")
	bucket := hostParts[0]
	var region string
	if len(hostParts) > 1 {
		region = hostParts[1]
	}

	var size int
	if ssize := os.Getenv("JFS_NUM_GOOGLE_CLIENTS"); ssize != "" {
		if size, err = strconv.Atoi(ssize); err != nil {
			return nil, err
		}
	}
	if size < 1 {
		size = 5
	}
	clis := make([]*storage.Client, size)

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Print and inspect the endpoint value; correct malformed characters, quotes, or whitespace
  2. Use a valid form like `gs://bucket.storage.googleapis.com` or `gs://bucket` (scheme is added automatically)
  3. If building the endpoint from env vars, ensure the variable is set and trimmed
  4. Validate locally with url.ParseRequestURI before passing the endpoint

Example fix

// before
endpoint := "gs://bucket..storage.googleapis.com:badport"
// after
endpoint := "gs://mybucket.storage.googleapis.com"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.ParseRequestURI(strings.Contains(ep, "://") ? ep : "gs://"+ep)
if err != nil { return fmt.Errorf("invalid gs endpoint %q: %v", ep, err) }

Type guard

func validGSEndpoint(ep string) bool {
  if !strings.Contains(ep, "://") { ep = "gs://" + ep }
  _, err := url.ParseRequestURI(ep)
  return err == nil
}

Try / catch

gs, err := newGS(endpoint, ak, sk, token)
if err != nil {
    if strings.HasPrefix(err.Error(), "Invalid endpoint") { return fmt.Errorf("check --endpoint format: %w", err) }
    return err
}

Prevention

When it happens

Trigger: Calling newGS (directly or via `juicefs format`/object storage selection) with a malformed endpoint such as `gs://[bad`, `gs://host:.:port`, or a string containing invalid URL characters so url.ParseRequestURI fails.

Common situations: Typo or stray whitespace/control characters in the endpoint passed via --storage gs and --endpoint, copy-pasting an endpoint with quotes or trailing characters, or environments where the endpoint is assembled from variables that are empty or malformed.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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