hyperledger/fabric · error
consenter %s:%d has invalid certificates
Error message
consenter %s:%d has invalid certificates
What it means
When a config update adds consenter nodes, each newly added node's TLS certificates are validated for expiration and trust against the verify options (orderer/consensus/etcdraft/chain.go:1539). This error wraps the validation failure (e.g. expired certificate or untrusted chain) for a specific host:port. The config update is rejected so a bad node never joins the raft cluster.
Source
Thrown at orderer/consensus/etcdraft/chain.go:1539
}
return nil
}
// create the dummy parameters for ComputeMembershipChanges
c.raftMetadataLock.RLock()
dummyOldBlockMetadata := proto.Clone(c.opts.BlockMetadata).(*etcdraft.BlockMetadata)
c.raftMetadataLock.RUnlock()
dummyOldConsentersMap := CreateConsentersMap(dummyOldBlockMetadata, oldMetadata)
changes, err := ComputeMembershipChanges(dummyOldBlockMetadata, dummyOldConsentersMap, newMetadata.GetConsenters())
if err != nil {
return err
}
// new config metadata was verified above. Additionally need to check new consenters for certificates expiration
for _, c := range changes.AddedNodes {
if err := validateConsenterTLSCerts(c, verifyOpts, false); err != nil {
return errors.Wrapf(err, "consenter %s:%d has invalid certificates", c.GetHost(), c.GetPort())
}
}
active := c.ActiveNodes.Load().([]uint64)
if changes.UnacceptableQuorumLoss(active) {
c.logger.Debugf("%d out of %d nodes are alive - %+v", len(active), len(dummyOldConsentersMap), active)
return errors.Errorf("%d out of %d nodes are alive, configuration will result in quorum loss", len(active), len(dummyOldConsentersMap))
}
return nil
}
// StatusReport returns the ConsensusRelation & Status
func (c *Chain) StatusReport() (types.ConsensusRelation, types.Status) {
c.statusReportMutex.Lock()
defer c.statusReportMutex.Unlock()
return c.consensusRelation, c.statusView on GitHub (pinned to 2736b63f8f)
Solutions
- Read the wrapped cause and re-issue fresh TLS certs for the named consenter
- Sign the new node's certs with a CA present in Orderer.TLS.RootCAs
- Update the channel config with the renewed certs and resubmit the update
- Synchronize the new node's system clock before generating certs
Example fix
// before fabric-ca-client enroll -u https://admin:pw@ca:7054 --tls.certfiles old-ca.pem // cert from unconfigured/expired CA // after fabric-ca-client enroll -u https://admin:pw@ca:7054 --tls.certfiles config-rootca.pem // cert chaining to Orderer.TLS.RootCAs
Defensive patterns
Strategy: validation
Validate before calling
for _, c := range changes.AddedNodes {
if err := validateConsenterTLSCerts(c, verifyOpts, false); err != nil {
return fmt.Errorf("pre-check failed for %s:%d: %w", c.GetHost(), c.GetPort(), err)
}
} Type guard
func certsFresh(c *common.Consenter, now time.Time) bool {
cert, err := parseCert(c.GetServerTlsCert())
return err == nil && now.After(cert.NotBefore) && now.Before(cert.NotAfter)
} Try / catch
if err := submitConfigUpdate(cfg); err != nil {
if strings.Contains(err.Error(), "has invalid certificates") {
// re-enroll the named consenter with a CA in RootCAs and resubmit
}
} Prevention
- Renew node certs before their expiry when adding them to a cluster
- Use monitoring on certificate lifetimes for orderer nodes
- Enroll new nodes only from CAs present in the channel config
When it happens
Trigger: A config update that adds a consenter whose TLS server or client certificate fails validateConsenterTLSCerts — expired cert, cert not yet valid, or no chain to a root CA in the verify options.
Common situations: Enrolling new orderer nodes with certificates that are already expired or issued by a non-configured CA; long-lived environments where node certs lapsed before joining; generating certs with a clock-skewed machine.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- without a system channel, a follower should have been create
- duplicate consenter: server cert: %s, client cert: %s
- No suitable BFT consenter for Raft consenter: %v
- failed to create x509 verify options from old and new ordere
- invalid new config metadata
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/d66c48ce3e069e64.
Report an issue: GitHub.