code: func CheckConfigMetadata(metadata *etcdraft.ConfigMetadata) error {
  	if metadata == nil {
  		// defensive check. this should not happen as CheckConfigMetadata
  		// should always be called with non-nil config metadata
  		return errors.Errorf("nil Raft config metadata")
  	}
  
  	if metadata.Options.HeartbeatTick == 0 ||
  		metadata.Options.ElectionTick == 0 ||
  		metadata.Options.MaxInflightBlocks == 0 {
  		// if SnapshotIntervalSize is zero, DefaultSnapshotIntervalSize is used
  		return errors.Errorf("none of HeartbeatTick (%d), ElectionTick (%d) and MaxInflightBlocks (%d) can be zero",
  			metadata.Options.HeartbeatTick, metadata.Options.ElectionTick, metadata.Options.MaxInflightBlocks)
  	}
  
  	// check Raft options
  	if metadata.Options.ElectionTick <= metadata.Options.HeartbeatTick {
  		return errors.Errorf("ElectionTick (%d) must be greater than HeartbeatTick (%d)",
  			metadata.Options.HeartbeatTick, metadata.Options.HeartbeatTick)
  	}
  
  	if d, err := time.ParseDuration(metadata.Options.TickInterval); err != nil {
  		return errors.Errorf("failed to parse TickInterval (%s) to time duration: %s", metadata.Options.TickInterval, err)
  	} else if d == 0 {
  		return errors.Errorf("TickInterval cannot be zero")
  	}
  
  	if len(metadata.Consenters) == 0 {
  		return errors.Errorf("empty consenter set")
  	}
  
  	// sanity check of certificates
  	for _, consenter := range metadata.Consenters {
  		if err := validateCert(consenter.ServerTlsCert, "server"); err != nil {
  			return err
  		}
  		if err := validateCert(consenter.ClientTlsCert, "client"); err != nil {
  			return err
  		}
  	}
  
  	if err := MetadataHasDuplication(metadata); err != nil {
  		return err
  	}
  
  	return nil
  }
docs: // CheckConfigMetadata validates Raft config metadata