cloudflare/cloudflared · error

failed to send request

Error message

failed to send request

What it means

SignCert POSTs the marshalled payload to the issuer URL (claims.Issuer + /cdn-cgi/access/cert_sign) with a 10-second HTTP client timeout. This error wraps any transport-level failure of that request: DNS failure, connection refused, TLS errors, or the timeout.

Source

Thrown at sshgen/sshgen.go:123

		PublicKey: pubKey,
		JWT:       token,
		Issuer:    claims.Issuer,
	})
	if err != nil {
		return "", errors.Wrap(err, "failed to marshal signPayload")
	}
	var res *http.Response
	if mockRequest != nil {
		res, err = mockRequest(claims.Issuer+signEndpoint, "application/json", bytes.NewBuffer(buf))
	} else {
		client := http.Client{
			Timeout: 10 * time.Second,
		}
		res, err = client.Post(claims.Issuer+signEndpoint, "application/json", bytes.NewBuffer(buf))
	}

	if err != nil {
		return "", errors.Wrap(err, "failed to send request")
	}
	defer res.Body.Close()

	decoder := json.NewDecoder(res.Body)

	if res.StatusCode != 200 {
		var errResponse errorResponse
		if err := decoder.Decode(&errResponse); err != nil {
			return "", err
		}
		return "", fmt.Errorf("%d: %s", errResponse.Status, errResponse.Message)
	}

	var signRes signResponse
	if err := decoder.Decode(&signRes); err != nil {
		return "", errors.Wrap(err, "failed to decode HTTP response")
	}
	return signRes.Certificate, nil

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Check network connectivity and that the issuer hostname resolves (dig/nslookup)
  2. Confirm the issuer URL in the JWT is the correct Cloudflare Access domain
  3. Increase or verify the 10s timeout is sufficient for your network (edit sshgen.go client Timeout)
  4. Check corporate proxies/firewalls that may block POSTs to the sign endpoint

Example fix

// before
client := http.Client{Timeout: 10 * time.Second}
// after
client := http.Client{Timeout: 30 * time.Second}
Defensive patterns

Strategy: retry

Validate before calling

// check the issuer endpoint is reachable before signing
u, err := url.Parse(issuer)
if err != nil || u.Scheme == "" || u.Host == "" {
    return fmt.Errorf("invalid issuer URL: %q", issuer)
}
conn, err := net.DialTimeout("tcp", net.JoinHostPort(u.Hostname(), portOr(u, "443")), 3*time.Second)
if err != nil {
    return fmt.Errorf("issuer unreachable: %w", err)
}
conn.Close()

Try / catch

cert, err := SignCert(token, pubKey)
if err != nil && strings.Contains(err.Error(), "failed to send request") {
    // retry with backoff for transient network issues
    time.Sleep(2 * time.Second)
    cert, err = SignCert(token, pubKey)
}

Prevention

When it happens

Trigger: client.Post fails because the issuer host is unreachable, DNS does not resolve, the network is down, TLS handshake fails, or the 10s timeout elapses.

Common situations: No internet/VPN connectivity; issuer URL misconfigured in the Access token; corporate proxy blocking the endpoint; slow network exceeding the 10s timeout.

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/ff9dafa1665d4ebf. Report an issue: GitHub.