valyala/fasthttp · error
cannot load tls key pair from cert file=%q and key file=%q:
Error message
cannot load tls key pair from cert file=%q and key file=%q: %w
What it means
Returned by Server.AppendCert when tls.LoadX509KeyPair fails to read or parse the certificate and key files. The library wraps the crypto/tls error with both file paths so misconfigured TLS assets are easy to diagnose. The server cannot enable TLS without a valid key pair.
Source
Thrown at server.go:1931
if err != nil {
return err
}
s.mu.Lock()
s.appendCertLocked(&cert)
s.mu.Unlock()
return nil
}
func loadX509KeyPair(certFile, keyFile string) (tls.Certificate, error) {
if certFile == "" && keyFile == "" {
return tls.Certificate{}, errNoCertOrKeyProvided
}
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return tls.Certificate{}, fmt.Errorf("cannot load tls key pair from cert file=%q and key file=%q: %w", certFile, keyFile, err)
}
return cert, nil
}
// AppendCertEmbed does the same as AppendCert but using in-memory data.
func (s *Server) AppendCertEmbed(certData, keyData []byte) error {
cert, err := x509KeyPair(certData, keyData)
if err != nil {
return err
}
s.mu.Lock()
s.appendCertLocked(&cert)
s.mu.Unlock()
return nil
}
View on GitHub (pinned to c96f600972)
Solutions
- Verify both files exist and are readable by the server user (ls -l; fix paths/permissions).
- Validate the pair offline: openssl x509 -noout -modulus -in cert; openssl rsa -noout -modulus -in key — confirm hashes match.
- Ensure the cert file contains the full chain in PEM format and the key is PEM (not DER/encrypted without handling).
- Renew/replace the certificate if expired, and redeploy both files together.
Example fix
// before
app.AppendCert("/etc/certs/cert.pem", "/etc/certs/key.pem") // key mismatch
// after
# regenerate matching pair, then:
err := app.AppendCert("/etc/certs/fullchain.pem", "/etc/certs/privkey.pem")
if err != nil { log.Fatal(err) } Defensive patterns
Strategy: validation
Validate before calling
func validateCertFiles(certFile, keyFile string) error {
cert, err := os.ReadFile(certFile)
if err != nil { return fmt.Errorf("cert unreadable: %w", err) }
key, err := os.ReadFile(keyFile)
if err != nil { return fmt.Errorf("key unreadable: %w", err) }
if _, err := tls.X509KeyPair(cert, key); err != nil {
return fmt.Errorf("invalid pair: %w", err)
}
return nil
} Try / catch
if err := app.AppendCert(certFile, keyFile); err != nil {
if strings.Contains(err.Error(), "cannot load tls key pair") {
log.Fatalf("check cert/key paths, permissions, and matching pair: %v", err)
}
log.Fatal(err)
} Prevention
- Pre-validate cert/key with openssl or tls.X509KeyPair in CI.
- Mount secrets with correct permissions and paths in orchestrators.
- Always deploy cert and key together as one versioned unit.
- Use fullchain PEM for certs; monitor expiry and rotate proactively.
When it happens
Trigger: Calling AppendCert (or ListenAndServeTLS configuration paths) with certFile/keyFile paths that don't exist, are unreadable (permissions), contain invalid PEM, have a key that doesn't match the certificate, or are expired/malformed certificates.
Common situations: Typo in cert/key paths relative to the working directory; secrets mounted with wrong permissions in Kubernetes; concatenating fullchain incorrectly; key regenerated while cert stayed old (mismatch); Let's Encrypt renewal replaced files while old data cached.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- cannot determine tls server name from addr %q: %w
- cannot load tls key pair from the provided cert data(%d) and
- fasthttp: hostclient can't follow redirects to a different p
- fasthttp: tls handshake timed out
- must implement readat
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/688dbd952af439c3.
Report an issue: GitHub.