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

  1. Verify both files exist and are readable by the server user (ls -l; fix paths/permissions).
  2. Validate the pair offline: openssl x509 -noout -modulus -in cert; openssl rsa -noout -modulus -in key — confirm hashes match.
  3. Ensure the cert file contains the full chain in PEM format and the key is PEM (not DER/encrypted without handling).
  4. 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

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

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/688dbd952af439c3. Report an issue: GitHub.