diff --git a/api/client.go b/api/client.go
index 7885a70538470983de0779ce39280539f012c783..7c5a7a9b455ee89b6162ca921027bc2c81e95df1 100644
--- a/api/client.go
+++ b/api/client.go
@@ -24,7 +24,6 @@ import (
 	"gitlab.com/elixxir/client/rekey"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/comms/connect"
-	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/large"
 	"gitlab.com/elixxir/crypto/signature/rsa"
@@ -48,8 +47,6 @@ type Client struct {
 	registrationVersion string
 }
 
-var noNDFErr = errors.New("Failed to get ndf from permissioning: rpc error: code = Unknown desc = Permissioning server does not have an ndf to give to client")
-
 //used to report the state of registration
 type OperationProgressCallback func(int)
 
@@ -79,11 +76,6 @@ func NewClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinit
 	cl.storage = store
 	cl.commManager = io.NewReceptionManager(cl.rekeyChan)
 	cl.ndf = ndfJSON
-	//build the topology
-	nodeIDs := make([]*id.Node, len(cl.ndf.Nodes))
-	for i, node := range cl.ndf.Nodes {
-		nodeIDs[i] = id.NewNodeFromBytes(node.ID)
-	}
 
 	//Create the cmix group and init the registry
 	cmixGrp := cyclic.NewGroup(
@@ -265,19 +257,23 @@ func FormatTextMessage(message string) []byte {
 var sessionFileError = errors.New("Session file cannot be loaded and " +
 	"is possibly corrupt. Please contact support@xxmessenger.io")
 
-// Logs in user and sets session on client object
-// returns the nickname or error if login fails
-func (cl *Client) StartMessageReceiver(callback func(error)) error {
+func (cl *Client) InitListeners() error {
 	transmitGateway := id.NewNodeFromBytes(cl.ndf.Nodes[0].ID).NewGateway()
 	transmissionHost, ok := cl.commManager.Comms.GetHost(transmitGateway.String())
 	if !ok {
 		return errors.New("Failed to retrieve host for transmission")
 	}
+
 	// Initialize UDB and nickname "bot" stuff here
 	bots.InitBots(cl.session, cl.commManager, cl.topology, id.NewUserFromBytes(cl.ndf.UDB.ID), transmissionHost)
 	// Initialize Rekey listeners
 	rekey.InitRekey(cl.session, cl.commManager, cl.topology, cl.rekeyChan)
+	return nil
+}
 
+// Logs in user and sets session on client object
+// returns the nickname or error if login fails
+func (cl *Client) StartMessageReceiver(callback func(error)) error {
 	pollWaitTimeMillis := 1000 * time.Millisecond
 	// TODO Don't start the message receiver if it's already started.
 	// Should be a pretty rare occurrence except perhaps for mobile.
@@ -518,7 +514,7 @@ func SetLogOutput(w goio.Writer) {
 	globals.Log.SetLogOutput(w)
 }
 
-// GetSession returns the session object for external access.  Access at your
+// GetSession returns the session object for external access.  Access at yourx
 // own risk
 func (cl *Client) GetSession() user.Session {
 	return cl.session
@@ -565,72 +561,3 @@ func (cl *Client) WriteToSessionFile(replacement string, store globals.Storage)
 
 	return nil
 }
-
-//GetUpdatedNDF: Connects to the permissioning server to get the updated NDF from it
-func (cl *Client) getUpdatedNDF() (*ndf.NetworkDefinition, error) { // again, uses internal ndf.  stay here, return results instead
-
-	//Hash the client's ndf for comparison with registration's ndf
-	hash := sha256.New()
-	ndfBytes := cl.ndf.Serialize()
-	hash.Write(ndfBytes)
-	ndfHash := hash.Sum(nil)
-
-	//Put the hash in a message
-	msg := &mixmessages.NDFHash{Hash: ndfHash}
-
-	host, ok := cl.commManager.Comms.GetHost(PermissioningAddrID)
-	if !ok {
-		return nil, errors.New("Failed to find permissioning host")
-	}
-
-	//Send the hash to registration
-	response, err := cl.commManager.Comms.SendGetUpdatedNDF(host, msg)
-	if err != nil {
-		errMsg := fmt.Sprintf("Failed to get ndf from permissioning: %v", err)
-		return nil, errors.New(errMsg)
-	}
-
-	//If there was no error and the response is nil, client's ndf is up-to-date
-	if response == nil {
-		globals.Log.DEBUG.Printf("Client NDF up-to-date")
-		return nil, nil
-	}
-
-	//FixMe: use verify instead? Probs need to add a signature to ndf, like in registration's getupdate?
-
-	globals.Log.INFO.Printf("Remote NDF: %s", string(response.Ndf))
-
-	//Otherwise pull the ndf out of the response
-	updatedNdf, _, err := ndf.DecodeNDF(string(response.Ndf))
-	if err != nil {
-		//If there was an error decoding ndf
-		errMsg := fmt.Sprintf("Failed to decode response to ndf: %v", err)
-		return nil, errors.New(errMsg)
-	}
-	return updatedNdf, nil
-}
-
-//request calls getUpdatedNDF for a new NDF repeatedly until it gets an NDF
-func requestNdf(cl *Client) error {
-	// Continuously polls for a new ndf after sleeping until response if gotten
-	globals.Log.INFO.Printf("Polling for a new NDF")
-	newNDf, err := cl.getUpdatedNDF()
-
-	if err != nil {
-		//lets the client continue when permissioning does not provide NDFs
-		if err.Error() == noNDFErr.Error() {
-			globals.Log.WARN.Println("Continuing without an updated NDF")
-			return nil
-		}
-
-		errMsg := fmt.Sprintf("Failed to get updated ndf: %v", err)
-		globals.Log.ERROR.Printf(errMsg)
-		return errors.New(errMsg)
-	}
-
-	if newNDf != nil {
-		cl.ndf = newNDf
-	}
-
-	return nil
-}
diff --git a/api/connect.go b/api/connect.go
index 86baa3b6ce7e1758c2c28476b0a1fc6a74bf0d49..e449638bc14b2a827d949bd663f2538b611d19eb 100644
--- a/api/connect.go
+++ b/api/connect.go
@@ -32,10 +32,12 @@ func (cl *Client) InitNetwork() error {
 		cl.registrationVersion = ver
 
 		//Request a new ndf from
-		err = requestNdf(cl)
+		def, err = io.GetUpdatedNDF(cl.ndf, cl.commManager.Comms)
 		if err != nil {
 			return err
-
+		}
+		if def != nil {
+			cl.ndf = def
 		}
 	} else {
 		globals.Log.WARN.Println("Registration not defined, not contacted")
@@ -90,19 +92,24 @@ func AddGatewayHosts(rm *io.ReceptionManager, definition *ndf.NetworkDefinition)
 		gwAddr := gateway.Address
 
 		_, err := rm.Comms.AddHost(gwID.String(), gwAddr, gwCreds, false)
-		if err != nil {
-			err = errors.Errorf("Failed to create host for gateway %s at %s: %+v",
-				gwID.String(), gwAddr, err)
-			if errs != nil {
-				errs = errors.Wrap(errs, err.Error())
-			} else {
-				errs = err
-			}
-		}
+		errs = handleError(errs, err, gwID.String(), gwAddr)
 	}
 	return errs
 }
 
+func handleError(base, err error, id, addr string) error {
+	if err != nil {
+		err = errors.Errorf("Failed to create host for gateway %s at %s: %+v",
+			id, addr, err)
+		if base != nil {
+			base = errors.Wrap(base, err.Error())
+		} else {
+			base = err
+		}
+	}
+	return base
+}
+
 // There's currently no need to keep connected to permissioning constantly,
 // so we have functions to connect to and disconnect from it when a connection
 // to permissioning is needed
diff --git a/bindings/client.go b/bindings/client.go
index fad99df03b562d0aad6e207753caef23e4ef123e..58872b0a2aab3319b9625192185ba7e3fdff6fed 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -351,3 +351,8 @@ func (cl *Client) WriteToSession(replacement string, storage globals.Storage) er
 	globals.Log.INFO.Printf("Binding call: WriteToSession")
 	return cl.client.WriteToSessionFile(replacement, storage)
 }
+
+func (cl *Client) InitListeners() error {
+	globals.Log.INFO.Printf("Binding call: InitListeners")
+	return cl.client.InitListeners()
+}
diff --git a/cmd/root.go b/cmd/root.go
index c6ee1af77d70ff453017ffd6e513496be44176b1..138c8b72946dc67f75cc0d7e484fa998de0071d2 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -389,8 +389,12 @@ var rootCmd = &cobra.Command{
 		cb := func(err error) {
 			globals.Log.ERROR.Print(err)
 		}
-		err := client.StartMessageReceiver(cb)
+		err := client.InitListeners()
+		if err != nil {
+			globals.Log.FATAL.Panicf("Could not initialize receivers: %s\n", err)
+		}
 
+		err = client.StartMessageReceiver(cb)
 		if err != nil {
 			globals.Log.FATAL.Panicf("Could Not start message reciever: %s\n", err)
 		}
diff --git a/io/interface.go b/io/interface.go
index c7253fda1c7b24b8f82ffc99a7d47e4dd418ab32..1aaf3ce3b57bec5b6ba485da40fe69e906c0e591 100644
--- a/io/interface.go
+++ b/io/interface.go
@@ -15,7 +15,7 @@ import (
 )
 
 // Communication interface implements send/receive functionality with the server
-type Communications interface { // this can go
+type Communications interface {
 	// SendMessage to the server
 
 	// TODO(nen) Can we get rid of the crypto type param here?
diff --git a/io/receive.go b/io/receive.go
index f5cb0991f20fecbe6ec81a61c679c413878e96ab..2eece09ddcebf06d0bd8e811e15fa9a831ca7076 100644
--- a/io/receive.go
+++ b/io/receive.go
@@ -81,7 +81,8 @@ func (rm *ReceptionManager) MessageReceiver(session user.Session, delay time.Dur
 					globals.Log.WARN.Printf("Rate limit excceded on gateway, pausing polling for 5 seconds")
 					time.Sleep(5 * time.Second)
 				}
-				callback(err)
+				go callback(err)
+				return
 			}
 			NumMessages += len(encryptedMessages)
 		case <-rm.rekeyChan:
diff --git a/io/updateNdf.go b/io/updateNdf.go
new file mode 100644
index 0000000000000000000000000000000000000000..cad01b158752600f109f4d5cf4de23c61e31b911
--- /dev/null
+++ b/io/updateNdf.go
@@ -0,0 +1,60 @@
+package io
+
+import (
+	"crypto/sha256"
+	"fmt"
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/globals"
+	"gitlab.com/elixxir/comms/client"
+	"gitlab.com/elixxir/comms/mixmessages"
+	"gitlab.com/elixxir/primitives/ndf"
+)
+
+var noNDFErr = errors.New("Failed to get ndf from permissioning: rpc error: code = Unknown desc = Permissioning server does not have an ndf to give to client")
+
+//GetUpdatedNDF: Connects to the permissioning server to get the updated NDF from it
+func GetUpdatedNDF(currentDef *ndf.NetworkDefinition, comms *client.Comms) (*ndf.NetworkDefinition, error) {
+	//Hash the client's ndf for comparison with registration's ndf
+	hash := sha256.New()
+	ndfBytes := currentDef.Serialize()
+	hash.Write(ndfBytes)
+	ndfHash := hash.Sum(nil)
+
+	//Put the hash in a message
+	msg := &mixmessages.NDFHash{Hash: ndfHash}
+
+	host, ok := comms.GetHost(PermissioningAddrID)
+	if !ok {
+		return nil, errors.New("Failed to find permissioning host")
+	}
+
+	//Send the hash to registration
+	response, err := comms.SendGetUpdatedNDF(host, msg)
+	if err != nil {
+		errMsg := fmt.Sprintf("Failed to get ndf from permissioning: %v", err)
+		if errMsg == noNDFErr.Error() {
+			globals.Log.WARN.Println("Continuing without an updated NDF")
+			return nil, nil
+		}
+		return nil, errors.New(errMsg)
+	}
+
+	//If there was no error and the response is nil, client's ndf is up-to-date
+	if response == nil {
+		globals.Log.DEBUG.Printf("Client NDF up-to-date")
+		return nil, nil
+	}
+
+	//FixMe: use verify instead? Probs need to add a signature to ndf, like in registration's getupdate?
+
+	globals.Log.INFO.Printf("Remote NDF: %s", string(response.Ndf))
+
+	//Otherwise pull the ndf out of the response
+	updatedNdf, _, err := ndf.DecodeNDF(string(response.Ndf))
+	if err != nil {
+		//If there was an error decoding ndf
+		errMsg := fmt.Sprintf("Failed to decode response to ndf: %v", err)
+		return nil, errors.New(errMsg)
+	}
+	return updatedNdf, nil
+}