cloudflare/cloudflared · error
can't create %s request
Error message
can't create %s request
What it means
RESTClient.sendRequest wraps http.NewRequest failures with 'can't create %s request' (method name interpolated). http.NewRequest fails when the URL string is unparseable or the body reader is invalid, so this means the request could not be constructed before any network call was made.
Source
Thrown at cfapi/base_client.go:99
Timeout: defaultTimeout,
},
log: log,
}, nil
}
func (r *RESTClient) sendRequest(method string, url url.URL, body interface{}) (*http.Response, error) {
var bodyReader io.Reader
if body != nil {
if bodyBytes, err := json.Marshal(body); err != nil {
return nil, errors.Wrap(err, "failed to serialize json body")
} else {
bodyReader = bytes.NewBuffer(bodyBytes)
}
}
req, err := http.NewRequest(method, url.String(), bodyReader)
if err != nil {
return nil, errors.Wrapf(err, "can't create %s request", method)
}
req.Header.Set("User-Agent", r.userAgent)
if bodyReader != nil {
req.Header.Set("Content-Type", jsonContentType)
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", r.authToken))
req.Header.Add("Accept", "application/json;version=1")
return r.client.Do(req)
}
func parseResponseEnvelope(reader io.Reader) (*response, error) {
// Schema for Tunnelstore responses in the v1 API.
// Roughly, it's a wrapper around a particular result that adds failures/errors/etc
var result response
// First, parse the wrapper and check the API call succeeded
if err := json.NewDecoder(reader).Decode(&result); err != nil {
return nil, errors.Wrap(err, "failed to decode response")
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Check the client's baseURL/accountTag/zoneTag for characters that break URL parsing.
- Log the target url.String() before the call to spot malformed URLs.
- Recreate the client with the default API base URL to isolate the issue.
- Ensure the body passed is a valid io.Reader (bytes.Buffer, strings.Reader).
Example fix
// before
client, _ := cfapi.NewRESTClient("ht tp://proxy", ...)
// after
client, _ := cfapi.NewRESTClient("http://proxy", ...) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(baseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid API base URL: %q", baseURL)
} Try / catch
resp, err := client.GetRouteByIP(t, ip)
if err != nil {
if strings.Contains(err.Error(), "can't create") {
return fmt.Errorf("malformed cfapi client URL: %w", err)
}
return err
} Prevention
- Validate baseURL with url.Parse before NewRESTClient.
- Log the request URL when wrapping client errors.
- Rebuild the client with defaults to isolate configuration problems.
When it happens
Trigger: Calling any RESTClient method when the client's endpoint URL is invalid (e.g. NewRESTClient got a baseURL that parseable initially but produces an unparseable final URL), or passing a bad io.Reader body.
Common situations: Custom/proxied API base URL misconfiguration; URL built with unescaped characters; misconfigured client instance shared across the app.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- failed to create account level endpoint
- failed to create route account-level endpoint
- failed to create virtual network account-level endpoint
- Error Parsing page %d
- failed to parse as URL: %w
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/320f2ea1d17b24f4.
Report an issue: GitHub.