fatedier/frp · error

tls.keyFile must be specified when tls is enabled

Error message

tls.keyFile must be specified when tls is enabled

What it means

Companion to the certFile check: when webServer.tls is enabled, tls.keyFile must also be non-empty. A certificate without its private key cannot complete the TLS handshake for the admin dashboard.

Source

Thrown at pkg/config/v1/validation/common.go:30

// See the License for the specific language governing permissions and
// limitations under the License.

package validation

import (
	"fmt"
	"slices"

	v1 "github.com/fatedier/frp/pkg/config/v1"
)

func validateWebServerConfig(c *v1.WebServerConfig) error {
	if c.TLS != nil {
		if c.TLS.CertFile == "" {
			return fmt.Errorf("tls.certFile must be specified when tls is enabled")
		}
		if c.TLS.KeyFile == "" {
			return fmt.Errorf("tls.keyFile must be specified when tls is enabled")
		}
	}

	return ValidatePort(c.Port, "webServer.port")
}

// ValidatePort checks that the network port is in range
func ValidatePort(port int, fieldPath string) error {
	if 0 <= port && port <= 65535 {
		return nil
	}
	return fmt.Errorf("%s: port number %d must be in the range 0..65535", fieldPath, port)
}

func validateLogConfig(c *v1.LogConfig) error {
	if !slices.Contains(SupportedLogLevels, c.Level) {
		return fmt.Errorf("invalid log level, optional values are %v", SupportedLogLevels)
	}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Set webServer.tls.keyFile to the matching private key path
  2. Ensure the key matches the certificate (frp will fail at startup if not)
  3. If TLS is not intended, drop the whole webServer.tls block

Example fix

# before
[webServer.tls]
certFile = "admin.crt"

# after
[webServer.tls]
certFile = "admin.crt"
keyFile = "admin.key"
Defensive patterns

Strategy: validation

Validate before calling

func webServerTLSComplete(c *v1.WebServerConfig) bool {
    return c.TLS == nil || (c.TLS.CertFile != "" && c.TLS.KeyFile != "")
}

Prevention

When it happens

Trigger: webServer.tls present with certFile set but keyFile empty/omitted; asymmetric config after switching from a combined PEM to separate files.

Common situations: Cert/key managed by different tools (cert renewed, key path not updated); template that fills certFile from a variable but leaves keyFile blank on some hosts.

Understand the failure class

Related errors


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