hyperledger/fabric · critical
unable to load cert at '%s'
Error message
unable to load cert at '%s'
What it means
Same flow as the key load: after successfully reading the key, loadDeliverServiceConfig reads the TLS certificate file and panics with this wrapped error if os.ReadFile fails. It aborts peer startup because the delivery service cannot be configured without its certificate.
Source
Thrown at core/deliverservice/config.go:206
if c.SecOpts.RequireClientCert {
certFile := config.GetPath("peer.tls.clientCert.file")
if certFile == "" {
certFile = config.GetPath("peer.tls.cert.file")
}
keyFile := config.GetPath("peer.tls.clientKey.file")
if keyFile == "" {
keyFile = config.GetPath("peer.tls.key.file")
}
keyPEM, err := os.ReadFile(keyFile)
if err != nil {
panic(errors.WithMessagef(err, "unable to load key at '%s'", keyFile))
}
c.SecOpts.Key = keyPEM
certPEM, err := os.ReadFile(certFile)
if err != nil {
panic(errors.WithMessagef(err, "unable to load cert at '%s'", certFile))
}
c.SecOpts.Certificate = certPEM
}
overridesMap, err := LoadOverridesMap()
if err != nil {
panic(err)
}
c.OrdererEndpointOverrides = overridesMap
policyKey := "peer.deliveryclient.policy"
policyMissing := !viper.IsSet(policyKey)
policy := DefaultPolicy
if policyMissing {
logger.Infof("%s is not set, defaulting to %s.", policyKey, policy)
} else {
policy = viper.GetString(policyKey)View on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the cert file path configured for the deliver service / peer.tls.cert.file exists and is readable.
- Confirm the TLS certificate volume/secret is mounted correctly in your container orchestration.
- Ensure the cert matches the configured key (same pair) and is PEM-encoded.
- Use absolute, verified paths and a startup preflight that checks both key and cert before launching the peer.
Example fix
// before
CORE_PEER_TLS_CERT_FILE=/tls/server.crt // not mounted in container
// after
# in deployment yaml
volumeMounts:
- name: tls
mountPath: /tls
# with CORE_PEER_TLS_CERT_FILE=/tls/server.crt verified present Defensive patterns
Strategy: validation
Validate before calling
certPath := viper.GetString("peer.tls.cert.file")
if certPath == "" {
return errors.New("peer.tls.cert.file not configured")
}
if fi, err := os.Stat(certPath); err != nil || fi.IsDir() {
return fmt.Errorf("TLS cert file missing: %s", certPath)
}
blk, _ := pem.Decode(mustRead(certPath))
if blk == nil || blk.Type != "CERTIFICATE" {
return errors.New("file is not a PEM certificate")
} Try / catch
// Config loading panics; preflight before starting the peer and, on failure, // surface errors.Cause(err) to distinguish missing file vs permission denial.
Prevention
- Preflight both members of the key/cert pair before startup.
- Confirm the cert matches the key (compare public keys/Modulus).
- Mount TLS secrets read-only and verify paths in deployment manifests.
- Re-provision certs (e.g. after rotation) before restarting peers.
When it happens
Trigger: TLS enabled but the certificate file path (deliver service cert config or peer.tls.cert.file) is empty, nonexistent, or unreadable when GlobalConfig initializes.
Common situations: Cert file not mounted into the container; typo in the cert path in core.yaml; expired/rotated certs removed before peer restart; permissions tightened by secret-management tooling.
Related errors
- unable to load key at '%s'
- invalid external builder configuration, path attribute missi
- external builder at path %s has no name attribute
- peer.address isn't set
- error loading TLS root certificate (%s)
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/5fb9e86bf0c5f0c8.
Report an issue: GitHub.