cloudflare/cloudflared · error

failed to create route account-level endpoint

Error message

failed to create route account-level endpoint

What it means

NewRESTClient builds the account-level teamnet routes endpoint (baseURL + /accounts/<accountTag>/teamnet/routes) with url.Parse and wraps failures with this message. Like the other endpoint construction errors, it fires only when the composed URL string is invalid.

Solutions

  1. Inspect baseURL and accountTag for illegal URL characters and trim them.
  2. Revert to the default Cloudflare API base URL if a custom one was set.
  3. Escape or validate the account tag before passing it to NewRESTClient.

Example fix

// before
accountTag := "abc def"
// after
accountTag := strings.TrimSpace("abcdef")
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(fmt.Sprintf("%s/accounts/%s/teamnet/routes", baseURL, accountTag))
if err != nil {
	return fmt.Errorf("invalid routes endpoint URL: %w", err)
}

Try / catch

client, err := cfapi.NewRESTClient(baseURL, accountTag, zoneTag, token, ua, log)
if err != nil {
	log.Error().Err(err).Str("baseURL", baseURL).Msg("cfapi client init failed")
	return err
}

Prevention

When it happens

Trigger: A baseURL or accountTag containing characters that make the composed routes URL unparseable (spaces, control chars, malformed percent-encoding).

Common situations: Misconfigured custom API base URL with stray characters; account tag pasted with hidden whitespace or shell-escaped characters.

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 cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/616476527d1f6924. Report an issue: GitHub.

Appendix: source

Thrown at cfapi/base_client.go:55

type baseEndpoints struct {
	accountLevel  url.URL
	zoneLevel     url.URL
	accountRoutes url.URL
	accountVnets  url.URL
}

var _ Client = (*RESTClient)(nil)

func NewRESTClient(baseURL, accountTag, zoneTag, authToken, userAgent string, log *zerolog.Logger) (*RESTClient, error) {
	baseURL = strings.TrimSuffix(baseURL, "/")
	accountLevelEndpoint, err := url.Parse(fmt.Sprintf("%s/accounts/%s/cfd_tunnel", baseURL, accountTag))
	if err != nil {
		return nil, errors.Wrap(err, "failed to create account level endpoint")
	}
	accountRoutesEndpoint, err := url.Parse(fmt.Sprintf("%s/accounts/%s/teamnet/routes", baseURL, accountTag))
	if err != nil {
		return nil, errors.Wrap(err, "failed to create route account-level endpoint")
	}
	accountVnetsEndpoint, err := url.Parse(fmt.Sprintf("%s/accounts/%s/teamnet/virtual_networks", baseURL, accountTag))
	if err != nil {
		return nil, errors.Wrap(err, "failed to create virtual network account-level endpoint")
	}
	zoneLevelEndpoint, err := url.Parse(fmt.Sprintf("%s/zones/%s/tunnels", baseURL, zoneTag))
	if err != nil {
		return nil, errors.Wrap(err, "failed to create account level endpoint")
	}
	httpTransport := http.Transport{
		TLSHandshakeTimeout:   defaultTimeout,
		ResponseHeaderTimeout: defaultTimeout,
	}
	_ = http2.ConfigureTransport(&httpTransport)
	return &RESTClient{
		baseEndpoints: &baseEndpoints{
			accountLevel:  *accountLevelEndpoint,
			zoneLevel:     *zoneLevelEndpoint,

View on GitHub (pinned to 2253eeeb25)