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.

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)

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.