ipfs/kubo · error

service endpoint should be provided without the /pins suffix

Error message

service endpoint should be provided without the /pins suffix

What it means

`normalizeEndpoint` also rejects endpoints whose path ends in `/pins`. The Pinning Service API client (`pinclient`) appends `/pins` itself when calling list/create endpoints, so a pre-suffixed endpoint would yield doubled paths like `/pins/pins` and broken requests. Kubo fails fast at registration/use time instead.

Source

Thrown at core/commands/pin/remotepin.go:810

func normalizeEndpoint(endpoint string) (string, error) {
	uri, err := neturl.ParseRequestURI(endpoint)
	if err != nil || !(uri.Scheme == "http" || uri.Scheme == "https") {
		return "", fmt.Errorf("service endpoint must be a valid HTTP URL")
	}

	// cleanup trailing and duplicate slashes (https://github.com/ipfs/kubo/issues/7826)
	uri.Path = gopath.Clean(uri.Path)
	uri.Path = strings.TrimSuffix(uri.Path, ".")
	uri.Path = strings.TrimSuffix(uri.Path, "/")

	// remove any query params
	if uri.RawQuery != "" {
		return "", fmt.Errorf("service endpoint should be provided without any query parameters")
	}

	if strings.HasSuffix(uri.Path, "/pins") {
		return "", fmt.Errorf("service endpoint should be provided without the /pins suffix")
	}

	return uri.String(), nil
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Strip the trailing `/pins` from the endpoint before registering: use `https://api.web3.storage` (or the provider's base path like `https://api.pinata.cloud/psa`).
  2. Consult the provider's kubo/IPFS pinning docs for the recommended base endpoint value.
  3. If already registered with the wrong URL, remove and re-add: `ipfs pin remote rm <name>` then `ipfs pin remote add <name> <base-endpoint> --key=<key>`.
  4. Remember kubo appends `/pins` automatically, so the stored endpoint must be the service root.

Example fix

// before
ipfs pin remote add web3.storage https://api.web3.storage/pins --key=$KEY
// after
ipfs pin remote add web3.storage https://api.web3.storage --key=$KEY
Defensive patterns

Strategy: validation

Validate before calling

#!/usr/bin/env bash
EP="$2"
if [[ "$EP" == */pins ]]; then
  echo "stripping redundant /pins suffix"
  EP="${EP%/pins}"
fi
ipfs pin remote add "$1" "$EP" --key="$KEY"

Prevention

When it happens

Trigger: Registering a service endpoint copied from API docs or a browser, e.g. `https://api.web3.storage/pins` or `https://api.pinata.cloud/psa/pins`, instead of the base endpoint.

Common situations: Copy-pasting the full PSA endpoint shown in a provider's curl examples; assuming kubo wants the exact endpoint you'd curl manually; provider docs listing the `/pins` resource URL rather than the service base URL.

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 ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/8b8ac3955d2ebcae. Report an issue: GitHub.