cloudflare/cloudflared · critical

unable to create TLS config to connect with edge

Error message

unable to create TLS config to connect with edge

What it means

When building per-protocol edge TLS configs in prepareTunnelConfig, tlsconfig.CreateTunnelConfig fails while constructing the *tls.Config used to dial Cloudflare's edge. This usually stems from a bad --cacert file, unreadable CA pool, or invalid TLS settings for the protocol. The failure aborts tunnel startup since no edge connection can be made securely.

Source

Thrown at cmd/cloudflared/tunnel/configuration.go:162

	if err != nil {
		return nil, nil, err
	}

	protocolSelector, err := connection.NewProtocolSelector(transportProtocol, log)
	if err != nil {
		return nil, nil, err
	}
	log.Info().Msgf("Initial protocol %s", protocolSelector.Current())

	edgeTLSConfigs := make(map[connection.Protocol]*tls.Config, len(connection.ProtocolList))
	for _, p := range connection.ProtocolList {
		tlsSettings := p.TLSSettings()
		if tlsSettings == nil {
			return nil, nil, fmt.Errorf("%s has unknown TLS settings", p)
		}
		edgeTLSConfig, err := tlsconfig.CreateTunnelConfig(c.String(flags.CACert), tlsSettings.ServerName)
		if err != nil {
			return nil, nil, errors.Wrap(err, "unable to create TLS config to connect with edge")
		}
		if len(tlsSettings.NextProtos) > 0 {
			edgeTLSConfig.NextProtos = tlsSettings.NextProtos
		}
		edgeTLSConfigs[p] = edgeTLSConfig
	}

	gracePeriod, err := gracePeriod(c)
	if err != nil {
		return nil, nil, err
	}
	edgeIPVersion, err := parseConfigIPVersion(c.String(flags.EdgeIpVersion))
	if err != nil {
		return nil, nil, err
	}
	edgeBindAddr, err := parseConfigBindAddress(c.String(flags.EdgeBindAddress))
	if err != nil {
		return nil, nil, err

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Verify the --cacert path exists, is readable, and contains valid PEM certificates (openssl x509 -in file -noout -text).
  2. Remove --cacert if you are not using a custom CA (default Cloudflare CA is used).
  3. Fix the tlsSettings/server name supplied by your tunnel configuration or token.
  4. Re-authenticate (`cloudflared tunnel login`) to regenerate valid certificate material.

Example fix

// before
cloudflared tunnel run --cacert /etc/cloudflared/missing.pem my-tunnel
// after
cloudflared tunnel run --cacert /etc/cloudflared/ca.pem my-tunnel  # valid PEM CA bundle
Defensive patterns

Strategy: validation

Validate before calling

// verify the CA cert file before starting
func caCertReadable(path string) error {
	if path == "" { return nil } // default CA used
	pem, err := os.ReadFile(path)
	if err != nil { return err }
	if !bytes.Contains(pem, []byte("BEGIN CERTIFICATE")) {
		return fmt.Errorf("%s is not a PEM CA bundle", path)
	}
	return nil
}

Try / catch

edgeTLSConfig, err := tlsconfig.CreateTunnelConfig(c.String(flags.CACert), tlsSettings.ServerName)
if err != nil {
	return nil, nil, errors.Wrap(err, "unable to create TLS config to connect with edge")
}

Prevention

When it happens

Trigger: Running with --cacert pointing to a missing, unreadable, or invalid PEM file; origin/edge TLS settings in config producing an unusable ServerName; internal error inside CreateTunnelConfig (e.g. loading the CA pool).

Common situations: Pointing --cacert at the origin certificate instead of a CA bundle; file permission problems in containers; stale config after rotating certificates; TLS settings in the tunnel token that reference an unknown server name.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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