temporalio/temporal · critical
loading server tls certificate failed: %v
Error message
loading server tls certificate failed: %v
What it means
getServerTLSConfigFromCertProvider fetches the server certificate from the configured cert provider and wraps any FetchServerCertificate failure as "loading server tls certificate failed: %v". It is raised during TLS config construction for the server (newServerTLSConfig or a callback) when the local-store cert provider cannot supply a server cert. The underlying provider error is formatted with %v, so the chain is not preserved.
Source
Thrown at common/rpc/encryption/local_store_tls_provider.go:333
return getServerTLSConfigFromCertProvider(certProvider, clientAuthRequired, remoteAddress, c.ServerName, logger)
}
return getServerTLSConfigFromCertProvider(certProvider, clientAuthRequired, remoteAddress, c.ServerName, logger)
}
return tlsConfig, nil
}
func getServerTLSConfigFromCertProvider(
certProvider CertProvider,
requireClientAuth bool,
remoteAddress string,
serverName string,
logger log.Logger) (*tls.Config, error) {
// Get serverCert from disk
serverCert, err := certProvider.FetchServerCertificate()
if err != nil {
return nil, fmt.Errorf("loading server tls certificate failed: %v", err)
}
// tls disabled, responsibility of cert provider above to error otherwise
if serverCert == nil {
return nil, nil
}
// Default to NoClientAuth
clientAuthType := tls.NoClientCert
var clientCaPool *x509.CertPool
// If mTLS enabled
if requireClientAuth {
clientAuthType = tls.RequireAndVerifyClientCert
ca, err := certProvider.FetchClientCAs()
if err != nil {
return nil, fmt.Errorf("failed to fetch client CAs: %v", err)View on GitHub (pinned to bde624efd1)
Solutions
- Inspect the wrapped %v text for the root cause (file not found, PEM decode, x509 parse) and fix the underlying provider input.
- Verify serverTLS.certFilePath and keyFilePath point to existing, readable PEM files.
- Check file permissions and that the secret/volume mount is present before service start.
- Validate the cert/key pair matches (openssl x509 -noout -modulus vs openssl rsa -noout -modulus).
Example fix
// before serverTLS: certFilePath: /etc/certs/server.crt # file does not exist // after serverTLS: certFilePath: /etc/temporal/tls/server.pem keyFilePath: /etc/temporal/tls/server-key.pem
Defensive patterns
Strategy: validation
Validate before calling
cert, err := os.ReadFile(cfg.CertFilePath)
if err != nil { return fmt.Errorf("server cert unreadable: %w", err) }
key, err := os.ReadFile(cfg.KeyFilePath)
if err != nil { return fmt.Errorf("server key unreadable: %w", err) }
if _, err := tls.X509KeyPair(cert, key); err != nil { return fmt.Errorf("bad server cert/key pair: %w", err) } Try / catch
cfg, err := getServerTLSConfigFromCertProvider(...)
if err != nil && strings.Contains(err.Error(), "loading server tls certificate failed") {
logger.Fatal("cannot start: server TLS cert invalid", "cause", err)
} Prevention
- Validate cert/key paths and permissions in deployment manifests before rollout.
- Use readiness probes that fail when TLS material is missing.
- Rotate secrets with atomic volume updates and re-verify after each rotation.
When it happens
Trigger: Server startup (newServerTLSConfig) or a refresh callback where certProvider.FetchServerCertificate() returns an error — e.g. cert file missing/unreadable, PEM decode failure (error 390), or x509 parse failure.
Common situations: Temporal server starting with a bad localStore TLS config: wrong CertFilePath/KeyFilePath, secrets not mounted, file permission denied, malformed certificate, or the cert provider's watch path pointing to a nonexistent directory.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to decode PEM certificate data
- failed to fetch client CAs: %v
- URI is invalid
- URI scheme does not match the archiver
- history was mutated
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/0f4786199209cb21.
Report an issue: GitHub.