diff --git a/routing/dht/query.go b/routing/dht/query.go
index aacab106f16d7377de05c8d6e649b04efb320063..888fdd65d61c7e43b50909573ea627017b57fa0b 100644
--- a/routing/dht/query.go
+++ b/routing/dht/query.go
@@ -52,6 +52,12 @@ type queryFunc func(context.Context, peer.ID) (*dhtQueryResult, error)
 
 // Run runs the query at hand. pass in a list of peers to use first.
 func (q *dhtQuery) Run(ctx context.Context, peers []peer.ID) (*dhtQueryResult, error) {
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	default:
+	}
+
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 
@@ -104,6 +110,15 @@ func (r *dhtQueryRunner) Run(peers []peer.ID) (*dhtQueryResult, error) {
 		r.addPeerToQuery(r.cg.Context(), p)
 	}
 
+	// may be closed already. this caused an odd race (where we attempt to
+	// add a child to an already closed ctxgroup). this is a temp workaround
+	// as we'll switch to using a proc here soon.
+	select {
+	case <-r.cg.Closed():
+		return nil, r.cg.Context().Err()
+	default:
+	}
+
 	// go do this thing.
 	// do it as a child func to make sure Run exits
 	// ONLY AFTER spawn workers has exited.