diff --git a/storage/e2e/session.go b/storage/e2e/session.go
index 2be837e613369b878a112912252919ce7e021de3..6172f56addb98baff180d5f0cd881c25b8577c79 100644
--- a/storage/e2e/session.go
+++ b/storage/e2e/session.go
@@ -154,6 +154,9 @@ func loadSession(ship *relationship, kv *versioned.KV,
 		return nil, errors.WithMessagef(err, "Failed to load %s", kv.GetFullKey(sessionKey))
 	}
 
+	obj, err := sessionUpgradeTable.Upgrade(obj)
+
+
 	err = session.unmarshal(obj.Data)
 	if err != nil {
 		return nil, err
diff --git a/storage/versioned/kv.go b/storage/versioned/kv.go
index 09a109a3aac30b5297d8ee2975d2e5e754e91e7a..d2c0f50615dbc2bfd772094e5e61810cc902a0ae 100644
--- a/storage/versioned/kv.go
+++ b/storage/versioned/kv.go
@@ -9,6 +9,7 @@ package versioned
 
 import (
 	"fmt"
+	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
@@ -57,8 +58,8 @@ func NewKV(data ekv.KeyValue) *KV {
 
 // Get gets and upgrades data stored in the key/value store
 // Make sure to inspect the version returned in the versioned object
-func (v *KV) Get(key string) (*Object, error) {
-	key = v.makeKey(key)
+func (v *KV) Get(key string, version uint64) (*Object, error) {
+	key = v.makeKey(key, version)
 	jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
 	// Get raw data
 	result := Object{}
@@ -69,22 +70,47 @@ func (v *KV) Get(key string) (*Object, error) {
 	return &result, nil
 }
 
+type UpgradeTable struct{
+	CurrentVersion uint64
+	Table []Upgrade
+}
+
 // Get gets and upgrades data stored in the key/value store
 // Make sure to inspect the version returned in the versioned object
-func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) {
-	key = v.makeKey(key)
-	jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
-	// Get raw data
-	result := &Object{}
-	err := v.r.data.Get(key, result)
-	if err != nil {
-		return nil, err
+func (v *KV) GetUpgrade(key string, ut UpgradeTable) (*Object, error) {
+	version := ut.CurrentVersion
+	key = v.makeKey(key, version)
+
+	if uint64(len(ut.Table))!=version{
+		jww.FATAL.Panicf("Cannot get upgrade for %s: table lengh (%d) " +
+			"does not match current version (%d)", key, len(ut.Table),
+			version)
+	}
+	var result *Object
+	for ;version>=0;version--{
+
+		key = v.makeKey(key, version)
+		jww.TRACE.Printf("Get %p with key %v", v.r.data, key)
+
+		// Get raw data
+		result = &Object{}
+		err := v.r.data.Get(key, result)
+		if err != nil {
+			jww.WARN.Printf("Failed to get keyvalue %s: %s", key, err)
+		}else{
+			break
+		}
+	}
+
+	if version < 0{
+		return nil, errors.Errorf("Failed to get key and upgrade it for %s", v.makeKey(key, ut.CurrentVersion))
 	}
 
+	var err error
 	initialVersion := result.Version
-	for result.Version<uint64(len(table)){
+	for result.Version<uint64(len(ut.Table)){
 		oldVersion := result.Version
-		result, err = table[oldVersion](result)
+		result, err = ut.Table[oldVersion](result)
 		if err!=nil{
 			jww.FATAL.Panicf("failed to upgrade key %s from " +
 				"version %v, initla version %v",  key, oldVersion,
@@ -97,8 +123,8 @@ func (v *KV) GetUpgrade(key string, table []Upgrade) (*Object, error) {
 
 
 // delete removes a given key from the data store
-func (v *KV) Delete(key string) error {
-	key = v.makeKey(key)
+func (v *KV) Delete(key string, version uint64) error {
+	key = v.makeKey(key, version)
 	jww.TRACE.Printf("delete %p with key %v", v.r.data, key)
 	return v.r.data.Delete(key)
 }
@@ -106,8 +132,8 @@ func (v *KV) Delete(key string) error {
 // Set upserts new data into the storage
 // When calling this, you are responsible for prefixing the key with the correct
 // type optionally unique id! Call MakeKeyWithPrefix() to do so.
-func (v *KV) Set(key string, object *Object) error {
-	key = v.makeKey(key)
+func (v *KV) Set(key string, version uint64, object *Object) error {
+	key = v.makeKey(key, version)
 	jww.TRACE.Printf("Set %p with key %v", v.r.data, key)
 	return v.r.data.Set(key, object)
 }
@@ -122,10 +148,10 @@ func (v *KV) Prefix(prefix string) *KV {
 }
 
 //Returns the key with all prefixes appended
-func (v *KV) GetFullKey(key string) string {
-	return v.prefix + key
+func (v *KV) GetFullKey(key string, version uint64) string {
+	return v.makeKey(key, version)
 }
 
-func (v *KV)makeKey(key string)string{
-	return v.prefix + key
+func (v *KV)makeKey(key string, version uint64)string{
+	return fmt.Sprintf("%s%s_%d", v.prefix, key, version)
 }
\ No newline at end of file