cloudflare/cloudflared · error

could not create TLS configuration: %w

Error message

could not create TLS configuration: %w

What it means

When serving a tunnel over HTTP/2, cloudflared builds a per-connection TLS config by cloning the base EdgeTLSConfigs entry and applying post-quantum curve preferences via cfdcrypto.TLSConfigWithCurvePreferences. If that fails (invalid base config, unsupported curve for the build, nil config), serveConnection returns this wrapped error and marks it recoverable so the supervisor can retry with backoff.

Source

Thrown at supervisor/tunnel.go:470

	)

	switch protocol {
	case connection.QUIC:
		// nolint: gosec
		connOptions := e.config.connectionOptions(addr.UDP.String(), uint8(backoff.Retries()))
		// nolint: zerologlint
		connOptions.LogFields(connLog.Logger().Debug().Uint8(connection.LogFieldConnIndex, connIndex)).Msgf("Tunnel connection options")
		return e.serveQUIC(ctx,
			addr.UDP.AddrPort(),
			connLog,
			connOptions,
			controlStream,
			connIndex)

	case connection.HTTP2:
		tlsConfig, err := cfdcrypto.TLSConfigWithCurvePreferences(e.config.EdgeTLSConfigs[protocol], e.config.connectionFeatures().PostQuantum)
		if err != nil {
			return fmt.Errorf("could not create TLS configuration: %w", err), true
		}

		connLog.Logger().Info().Msgf("Tunnel connection curve preferences: %v", tlsConfig.CurvePreferences)

		edgeConn, err := edgediscovery.DialEdge(ctx, dialTimeout, tlsConfig, addr.TCP, e.edgeBindAddr)
		if err != nil {
			connLog.ConnAwareLogger().Err(err).Msg("Unable to establish connection with Cloudflare edge")
			return err, true
		}

		// Rebuild the connection options with the local address now that the
		// edge socket is established.
		// nolint: gosec
		connOptions := e.config.connectionOptions(edgeConn.LocalAddr().String(), uint8(backoff.Retries()))
		// nolint: zerologlint
		connOptions.LogFields(connLog.Logger().Debug().Uint8(connection.LogFieldConnIndex, connIndex)).Msgf("Tunnel connection options")
		if err := e.serveHTTP2(
			ctx,

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Check earlier startup logs for CA/TLS initialization failures — the base EdgeTLSConfigs[HTTP2] may be nil or incomplete.
  2. If you passed --post-quantum, verify the build supports it (non-FIPS, recent cloudflared); try without the flag.
  3. Upgrade cloudflared to the latest version so curve preferences match edge requirements.
  4. Clear broken local config (cert.pem / CA pool) and re-run `cloudflared tunnel login` to regenerate credentials.
  5. Let protocol selection fall back from HTTP2 to QUIC (do not force --protocol http2) if the failure persists.
Defensive patterns

Strategy: type-guard

Type guard

func asError(r interface{}) (error, bool) {
	if err, ok := r.(error); ok {
		return err, true
	}
	return nil, false
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		err, ok := r.(error)
		if !ok {
			err = fmt.Errorf("ServeTunnel: %v", r)
		}
		log.Error().Str("stack", string(debug.Stack())).Msg("tunnel goroutine panicked")
		recoverable = true
	}
}()

Prevention

When it happens

Trigger: EdgeTLSConfigs lacks a valid *tls.Config for the HTTP2 protocol (e.g. CA/cert loading failed earlier), or TLSConfigWithCurvePreferences rejects the requested post-quantum curve combination for the current build/platform.

Common situations: Corrupt or missing origin/edge CA pool configuration; FIPS or post-quantum flag combinations unsupported in the binary; a bug where the base TLS config was never initialized before serveTunnel ran; misconfigured `--edge-ip-version`/protocol forced to HTTP2 on an exotic build.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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