gofiber/fiber · critical
tls: cannot load TLS key pair from certFile=%q and keyFile=%
Error message
tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %w
What it means
Returned by App.Listen when tls.LoadX509KeyPair fails to load the TLS certificate and private key pair. This happens at server startup when both Config.CertFile and Config.CertKeyFile are set but the files are missing, unreadable, or do not form a valid X.509 key pair. The error includes both file paths and the underlying tls error.
Source
Thrown at listen.go:214
// app.Listen(":8080")
// app.Listen("127.0.0.1:8080")
// app.Listen(":8080", ListenConfig{EnablePrefork: true})
func (app *App) Listen(addr string, config ...ListenConfig) error {
cfg := listenConfigDefault(config...)
// Configure TLS
var tlsConfig *tls.Config
var tlsHandler *TLSHandler
if cfg.TLSConfig != nil {
tlsConfig = cfg.TLSConfig.Clone()
} else {
switch {
case cfg.AutoCertManager != nil && (cfg.CertFile != "" || cfg.CertKeyFile != ""):
return ErrAutoCertWithCertFile
case cfg.CertFile != "" && cfg.CertKeyFile != "":
cert, err := tls.LoadX509KeyPair(cfg.CertFile, cfg.CertKeyFile)
if err != nil {
return fmt.Errorf("tls: cannot load TLS key pair from certFile=%q and keyFile=%q: %w", cfg.CertFile, cfg.CertKeyFile, err)
}
tlsHandler = &TLSHandler{}
tlsConfig = &tls.Config{
MinVersion: cfg.TLSMinVersion,
Certificates: []tls.Certificate{
cert,
},
GetCertificate: tlsHandler.GetClientInfo,
}
case cfg.AutoCertManager != nil:
tlsConfig = &tls.Config{
MinVersion: cfg.TLSMinVersion,
GetCertificate: cfg.AutoCertManager.GetCertificate,
NextProtos: []string{"http/1.1", "acme-tls/1"},
}
default:View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Verify both paths exist and are readable: ls -l cert.pem key.pem.
- Confirm cert and key match using openssl to compare the modulus of the cert and key.
- Use absolute paths for the cert and key files in production.
- Ensure PEM formatting (BEGIN/END CERTIFICATE and BEGIN/END PRIVATE KEY).
- For auto-rotating certs, prefer AutoCertManager or a custom TLSConfig with GetCertificate.
Example fix
// before
app.Listen(":443", fiber.ListenConfig{
CertFile: "cert", // wrong/missing file
CertKeyFile: "key",
})
// after
app.Listen(":443", fiber.ListenConfig{
CertFile: "/etc/tls/fullchain.pem",
CertKeyFile: "/etc/tls/privkey.pem",
}) Defensive patterns
Strategy: validation
Validate before calling
// Validate the cert/key pair at startup before Listen
if _, err := tls.LoadX509KeyPair(certFile, keyFile); err != nil {
log.Fatalf("invalid TLS key pair: %v", err)
} Try / catch
if err := app.Listen(":443", fiber.ListenConfig{
CertFile: certFile, CertKeyFile: keyFile,
}); err != nil {
log.Fatalf("server stopped: %v", err)
} Prevention
- Verify cert and key files exist and are readable before boot.
- Use absolute paths for TLS files in production.
- Confirm cert and key match by comparing their modulus.
- Use AutoCertManager or a GetCertificate hook for auto-rotation.
- Ensure PEM formatting for both files.
When it happens
Trigger: Calling app.Listen(":443", fiber.ListenConfig{CertFile: "cert.pem", CertKeyFile: "key.pem"}) where either file is missing, the key doesn't match the cert, the files are not PEM-encoded, or the process lacks read permission.
Common situations: Cert files not mounted into the container, paths relative to the wrong working directory, an expired/regenerated cert whose key wasn't updated in tandem, or permission issues on the secrets.
Related errors
- failed to read client CA file %q: %w
- tls: AutoCertManager cannot be combined with CertFile/CertKe
- proxy: HTTPS to HTTP redirect blocked
- failed to listen: %w
- failed to parse client CA certificate from %q
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/4a30b810daaf678e.json.
Report an issue: GitHub.