{"record":{"id":"10af797c8bbb50e1","repo":"ipfs/kubo","slug":"service-endpoint-must-be-a-valid-http-url","errorCode":null,"errorMessage":"service endpoint must be a valid HTTP URL","messagePattern":"service endpoint must be a valid HTTP URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/commands/pin/remotepin.go","lineNumber":796,"sourceCode":"\t}\n\tif cfg.Pinning.RemoteServices == nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"service not known\")\n\t}\n\tservice, present := cfg.Pinning.RemoteServices[name]\n\tif !present {\n\t\treturn \"\", \"\", fmt.Errorf(\"service not known\")\n\t}\n\tendpoint, err = normalizeEndpoint(service.API.Endpoint)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\treturn endpoint, service.API.Key, nil\n}\n\nfunc normalizeEndpoint(endpoint string) (string, error) {\n\turi, err := neturl.ParseRequestURI(endpoint)\n\tif err != nil || !(uri.Scheme == \"http\" || uri.Scheme == \"https\") {\n\t\treturn \"\", fmt.Errorf(\"service endpoint must be a valid HTTP URL\")\n\t}\n\n\t// cleanup trailing and duplicate slashes (https://github.com/ipfs/kubo/issues/7826)\n\turi.Path = gopath.Clean(uri.Path)\n\turi.Path = strings.TrimSuffix(uri.Path, \".\")\n\turi.Path = strings.TrimSuffix(uri.Path, \"/\")\n\n\t// remove any query params\n\tif uri.RawQuery != \"\" {\n\t\treturn \"\", fmt.Errorf(\"service endpoint should be provided without any query parameters\")\n\t}\n\n\tif strings.HasSuffix(uri.Path, \"/pins\") {\n\t\treturn \"\", fmt.Errorf(\"service endpoint should be provided without the /pins suffix\")\n\t}\n\n\treturn uri.String(), nil\n}","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/pin/remotepin.go#L778-L814","documentation":"`normalizeEndpoint` validates a remote pinning service endpoint before storing/using it. It parses the URL with `url.ParseRequestURI` and requires the scheme to be http or https. Anything unparseable, schemeless (e.g. `api.pinata.cloud` with no `https://`), or using another scheme (ftp:, file:) produces this error.","triggerScenarios":"`ipfs pin remote add <name> <endpoint>` (or config edit + use) where the endpoint lacks a scheme (`ipfs pin remote add pinata api.pinata.cloud/psa`), contains invalid URL characters, or uses a non-HTTP scheme.","commonSituations":"Omitting `https://` when copying a bare hostname from docs; trailing spaces or invisible characters in the endpoint from copy-paste; typos like `htp://` or `https:/` (single slash).","solutions":["Prefix the endpoint with its scheme: use `https://api.pinata.cloud/psa` instead of `api.pinata.cloud/psa`.","Check for typos in the scheme (`http://`, `https://`) and stray whitespace/characters; re-type the URL cleanly.","Ensure the whole URL is quoted in the shell if it contains `&` or `?` characters: `ipfs pin remote add name \"https://...\" --key=...`.","Validate locally: `go`-style check or simply confirm the URL opens in a browser before registering."],"exampleFix":"// before\nipfs pin remote add pinata api.pinata.cloud/psa --key=$KEY\n// after\nipfs pin remote add pinata https://api.pinata.cloud/psa --key=$KEY","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\nEP=\"$2\"\nif [[ \"$EP\" != http://* && \"$EP\" != https://* ]]; then\n  echo \"endpoint must start with http:// or https://\" >&2\n  exit 1\nfi\nipfs pin remote add \"$1\" \"$EP\" --key=\"$KEY\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include the scheme when copying endpoint URLs","Quote URLs in shell to avoid stray characters","Test the URL in a browser or with curl before registering"],"tags":["validation","url","remote-pinning","config"],"backgroundTag":"invalid-url","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}