fatedier/frp · error

gen TLS config error: %v

Error message

gen TLS config error: %v

What it means

The HTTPS-plugin server failed to build its TLS configuration from the certificate and key paths passed to New(). transport.NewServerTLSConfig loads and pairs crtPath/keyPath; any load or parse failure (missing file, bad PEM, key/cert mismatch) is wrapped into this error when creating the plugin's local https server.

Source

Thrown at pkg/plugin/client/internal/httpsserver/server.go:34

package httpsserver

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"time"

	"github.com/samber/lo"

	"github.com/fatedier/frp/pkg/transport"
	httppkg "github.com/fatedier/frp/pkg/util/http"
)

func New(handler http.Handler, crtPath, keyPath string, enableHTTP2 *bool) (*http.Server, error) {
	tlsConfig, err := transport.NewServerTLSConfig(crtPath, keyPath, "")
	if err != nil {
		return nil, fmt.Errorf("gen TLS config error: %v", err)
	}

	server := &http.Server{
		Handler:           withMisdirectedRequestCheck(handler),
		ReadHeaderTimeout: 60 * time.Second,
		TLSConfig:         tlsConfig,
	}
	if !lo.FromPtr(enableHTTP2) {
		server.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
	}
	return server, nil
}

func withMisdirectedRequestCheck(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.TLS != nil {
			tlsServerName, _ := httppkg.CanonicalHost(r.TLS.ServerName)
			host, _ := httppkg.CanonicalHost(r.Host)

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Check the wrapped %v error: file-not-found means fix the path; tls error 'failed to find any PEM data' means the file is not valid PEM
  2. Verify crtPath holds the certificate and keyPath the private key (not swapped), and that they match (same public key)
  3. Ensure the frp process can read both files (permissions, container volume mounts)
  4. Validate with: openssl x509 -in crt.pem -noout && openssl pkey -in key.pem -noout

Example fix

// before (frpc.toml)
[[proxies]]
name = "web"
type = "https"
[proxies.plugin]
type = "https2http"
crtPath = "/etc/wrong/cert.pem"
keyPath = "/etc/wrong/key.pem"

// after
crtPath = "/etc/frp/cert.pem"   # valid PEM certificate
keyPath = "/etc/frp/key.pem"    # matching PEM private key
Defensive patterns

Strategy: validation

Validate before calling

// Validate cert/key files before starting frpc
if _, err := tls.LoadX509KeyPair(crtPath, keyPath); err != nil {
    return fmt.Errorf("bad plugin cert/key: %w", err)
}

Try / catch

if _, err := httpsserver.New(h, crt, key, enableHTTP2); err != nil {
    log.Errorf("plugin TLS setup failed (check crtPath/keyPath): %v", err)
}

Prevention

When it happens

Trigger: Configuring an https2http/https2https type plugin server (v1.HTTPS2HTTPPluginOptions etc.) where pluginCRTPath/pluginKeyPath point to unreadable, malformed, or mismatched PEM files.

Common situations: Cert file path wrong or not mounted into the container; key and certificate swapped in config; expired/re-issued cert with stray text in the PEM; file permissions deny the frp process read access.

Understand the failure class

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/704ce70107b7fcb8. Report an issue: GitHub.