diff --git a/pkg/kotsadmsnapshot/backup.go b/pkg/kotsadmsnapshot/backup.go
index b0809c05e4..3a157ef4b2 100644
--- a/pkg/kotsadmsnapshot/backup.go
+++ b/pkg/kotsadmsnapshot/backup.go
@@ -1,6 +1,7 @@
 package snapshot
 
 import (
+	"bytes"
 	"context"
 	"crypto/sha256"
 	"encoding/json"
@@ -39,8 +40,10 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/fields"
 	"k8s.io/apimachinery/pkg/labels"
+	serializer "k8s.io/apimachinery/pkg/runtime/serializer/json"
 	"k8s.io/apimachinery/pkg/util/validation"
 	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/utils/ptr"
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
 )
@@ -236,7 +239,7 @@ func CreateInstanceBackup(ctx context.Context, cluster *downstreamtypes.Downstre
 
 	ctrlClient, err := k8sutil.GetKubeClient(ctx)
 	if err != nil {
-		return "", fmt.Errorf("failed to get kubeclient: %w", err)
+		return "", errors.Wrap(err, "failed to get kubeclient")
 	}
 
 	veleroClient, err := veleroclient.GetBuilder().GetVeleroClient(cfg)
@@ -324,6 +327,30 @@ func GetInstanceBackupCount(veleroBackup velerov1.Backup) int {
 	return 1
 }
 
+// GetInstanceBackupCount returns the restore CR from the velero backup object annotation.
+func GetInstanceBackupRestore(veleroBackup velerov1.Backup) (*velerov1.Restore, error) {
+	restoreSpec := veleroBackup.GetAnnotations()[types.InstanceBackupRestoreSpecAnnotation]
+	if restoreSpec == "" {
+		return nil, nil
+	}
+
+	restore, err := kotsutil.LoadRestoreFromContents([]byte(restoreSpec))
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to load restore from contents")
+	}
+
+	return restore, nil
+}
+
+func encodeRestoreSpec(restore *velerov1.Restore) (string, error) {
+	var b bytes.Buffer
+	s := serializer.NewSerializer(serializer.DefaultMetaFactory, scheme.Scheme, scheme.Scheme, false)
+	if err := s.Encode(restore, &b); err != nil {
+		return "", errors.Wrap(err, "failed to encode restore")
+	}
+	return strings.TrimSpace(b.String()), nil
+}
+
 // getInstanceBackupMetadata returns metadata about the instance backup for use in creating an
 // instance backup.
 func getInstanceBackupMetadata(ctx context.Context, k8sClient kubernetes.Interface, ctrlClient ctrlclient.Client, veleroClient veleroclientv1.VeleroV1Interface, cluster *downstreamtypes.Downstream, isScheduled bool) (instanceBackupMetadata, error) {
@@ -391,7 +418,7 @@ func getInstanceBackupMetadata(ctx context.Context, k8sClient kubernetes.Interfa
 
 		kotsKinds, err := kotsutil.LoadKotsKinds(archiveDir)
 		if err != nil {
-			return metadata, errors.Wrap(err, "failed to load kots kinds from path")
+			return metadata, errors.Wrapf(err, "failed to load kots kinds from path for app %s", app.Slug)
 		}
 
 		metadata.apps[app.Slug] = appInstanceBackupMetadata{
@@ -426,12 +453,12 @@ func getECInstanceBackupMetadata(ctx context.Context, ctrlClient ctrlclient.Clie
 
 	installation, err := embeddedcluster.GetCurrentInstallation(ctx, ctrlClient)
 	if err != nil {
-		return nil, fmt.Errorf("failed to get current installation: %w", err)
+		return nil, errors.Wrap(err, "failed to get current installation")
 	}
 
 	seaweedFSS3ServiceIP, err := embeddedcluster.GetSeaweedFSS3ServiceIP(ctx, ctrlClient)
 	if err != nil {
-		return nil, fmt.Errorf("failed to get seaweedfs s3 service ip: %w", err)
+		return nil, errors.Wrap(err, "failed to get seaweedfs s3 service ip")
 	}
 
 	return &ecInstanceBackupMetadata{
@@ -534,6 +561,7 @@ func getAppInstanceBackupSpec(k8sClient kubernetes.Interface, metadata instanceB
 	}
 
 	var appVeleroBackup *velerov1.Backup
+	var restore *velerov1.Restore
 
 	for _, appMeta := range metadata.apps {
 		// if there is both a backup and a restore spec this is using the new improved DR
@@ -545,11 +573,8 @@ func getAppInstanceBackupSpec(k8sClient kubernetes.Interface, metadata instanceB
 			return nil, errors.New("cannot create backup for Embedded Cluster with multiple apps")
 		}
 
-		if appMeta.kotsKinds.Backup == nil {
-			return nil, errors.New("backup spec is empty, this is unexpected")
-		}
-
 		appVeleroBackup = appMeta.kotsKinds.Backup.DeepCopy()
+		restore = appMeta.kotsKinds.Restore.DeepCopy()
 
 		appVeleroBackup.Name = ""
 		appVeleroBackup.GenerateName = "application-"
@@ -561,7 +586,11 @@ func getAppInstanceBackupSpec(k8sClient kubernetes.Interface, metadata instanceB
 		return nil, nil
 	}
 
-	var err error
+	restoreSpec, err := encodeRestoreSpec(restore)
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to encode restore spec")
+	}
+
 	appVeleroBackup.Annotations, err = appendCommonAnnotations(k8sClient, appVeleroBackup.Annotations, metadata)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to add annotations to application backup")
@@ -573,6 +602,7 @@ func getAppInstanceBackupSpec(k8sClient kubernetes.Interface, metadata instanceB
 	appVeleroBackup.Labels[types.InstanceBackupNameLabel] = metadata.backupName
 	appVeleroBackup.Annotations[types.InstanceBackupTypeAnnotation] = types.InstanceBackupTypeApp
 	appVeleroBackup.Annotations[types.InstanceBackupCountAnnotation] = strconv.Itoa(2)
+	appVeleroBackup.Annotations[types.InstanceBackupRestoreSpecAnnotation] = restoreSpec
 
 	appVeleroBackup.Spec.StorageLocation = "default"
 
diff --git a/pkg/kotsadmsnapshot/backup_test.go b/pkg/kotsadmsnapshot/backup_test.go
index 142d5e8b39..d58c807a7e 100644
--- a/pkg/kotsadmsnapshot/backup_test.go
+++ b/pkg/kotsadmsnapshot/backup_test.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"reflect"
 	"testing"
 	"time"
 
@@ -1626,7 +1627,18 @@ func Test_getAppInstanceBackupSpec(t *testing.T) {
 				},
 			},
 		},
-		Restore: &velerov1.Restore{},
+		Restore: &velerov1.Restore{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: "velero.io/v1",
+				Kind:       "Restore",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name: "test-restore",
+			},
+			Spec: velerov1.RestoreSpec{
+				BackupName: "test-backup",
+			},
+		},
 	}
 
 	ecMeta := &ecInstanceBackupMetadata{
@@ -1836,8 +1848,8 @@ func Test_getAppInstanceBackupSpec(t *testing.T) {
 			},
 			assert: func(t *testing.T, got *velerov1.Backup, err error) {
 				require.NoError(t, err)
-				if assert.Contains(t, got.Labels, "replicated.com/backup-name") {
-					assert.Equal(t, "app-1-17332487841234", got.Labels["replicated.com/backup-name"])
+				if assert.Contains(t, got.Labels, types.InstanceBackupNameLabel) {
+					assert.Equal(t, "app-1-17332487841234", got.Labels[types.InstanceBackupNameLabel])
 				}
 			},
 		},
@@ -1867,11 +1879,14 @@ func Test_getAppInstanceBackupSpec(t *testing.T) {
 			},
 			assert: func(t *testing.T, got *velerov1.Backup, err error) {
 				require.NoError(t, err)
-				if assert.Contains(t, got.Annotations, "replicated.com/backup-type") {
-					assert.Equal(t, "app", got.Annotations["replicated.com/backup-type"])
+				if assert.Contains(t, got.Annotations, types.InstanceBackupTypeAnnotation) {
+					assert.Equal(t, types.InstanceBackupTypeApp, got.Annotations[types.InstanceBackupTypeAnnotation])
+				}
+				if assert.Contains(t, got.Annotations, types.InstanceBackupCountAnnotation) {
+					assert.Equal(t, "2", got.Annotations[types.InstanceBackupCountAnnotation])
 				}
-				if assert.Contains(t, got.Annotations, "replicated.com/backup-count") {
-					assert.Equal(t, "2", got.Annotations["replicated.com/backup-count"])
+				if assert.Contains(t, got.Annotations, types.InstanceBackupRestoreSpecAnnotation) {
+					assert.Equal(t, `{"kind":"Restore","apiVersion":"velero.io/v1","metadata":{"name":"test-restore","creationTimestamp":null},"spec":{"backupName":"test-backup","hooks":{}},"status":{}}`, got.Annotations[types.InstanceBackupRestoreSpecAnnotation])
 				}
 			},
 		},
@@ -2347,9 +2362,9 @@ func Test_getInfrastructureInstanceBackupSpec(t *testing.T) {
 			},
 			assert: func(t *testing.T, got *velerov1.Backup, err error) {
 				require.NoError(t, err)
-				assert.NotContains(t, got.Labels, "replicated.com/backup-name")
-				assert.NotContains(t, got.Annotations, "replicated.com/backup-type")
-				assert.NotContains(t, got.Annotations, "replicated.com/backup-count")
+				assert.NotContains(t, got.Labels, types.InstanceBackupNameLabel)
+				assert.NotContains(t, got.Annotations, types.InstanceBackupTypeAnnotation)
+				assert.NotContains(t, got.Annotations, types.InstanceBackupCountAnnotation)
 			},
 		},
 		{
@@ -2379,14 +2394,14 @@ func Test_getInfrastructureInstanceBackupSpec(t *testing.T) {
 			},
 			assert: func(t *testing.T, got *velerov1.Backup, err error) {
 				require.NoError(t, err)
-				if assert.Contains(t, got.Labels, "replicated.com/backup-name") {
-					assert.Equal(t, "app-1-17332487841234", got.Labels["replicated.com/backup-name"])
+				if assert.Contains(t, got.Labels, types.InstanceBackupNameLabel) {
+					assert.Equal(t, "app-1-17332487841234", got.Labels[types.InstanceBackupNameLabel])
 				}
-				if assert.Contains(t, got.Annotations, "replicated.com/backup-type") {
-					assert.Equal(t, "infra", got.Annotations["replicated.com/backup-type"])
+				if assert.Contains(t, got.Annotations, types.InstanceBackupTypeAnnotation) {
+					assert.Equal(t, types.InstanceBackupTypeInfra, got.Annotations[types.InstanceBackupTypeAnnotation])
 				}
-				if assert.Contains(t, got.Annotations, "replicated.com/backup-count") {
-					assert.Equal(t, "2", got.Annotations["replicated.com/backup-count"])
+				if assert.Contains(t, got.Annotations, types.InstanceBackupCountAnnotation) {
+					assert.Equal(t, "2", got.Annotations[types.InstanceBackupCountAnnotation])
 				}
 			},
 		},
@@ -3386,3 +3401,66 @@ func TestListInstanceBackups(t *testing.T) {
 		})
 	}
 }
+
+func TestGetInstanceBackupRestore(t *testing.T) {
+	type args struct {
+		veleroBackup velerov1.Backup
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    *velerov1.Restore
+		wantErr bool
+	}{
+		{
+			name: "no restore spec",
+			args: args{
+				veleroBackup: velerov1.Backup{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: "test-backup",
+					},
+				},
+			},
+			want:    nil,
+			wantErr: false,
+		},
+		{
+			name: "with restore spec",
+			args: args{
+				veleroBackup: velerov1.Backup{
+					ObjectMeta: metav1.ObjectMeta{
+						Name: "test-backup",
+						Annotations: map[string]string{
+							types.InstanceBackupRestoreSpecAnnotation: `{"kind":"Restore","apiVersion":"velero.io/v1","metadata":{"name":"test-restore","creationTimestamp":null},"spec":{"backupName":"test-backup","hooks":{}},"status":{}}`,
+						},
+					},
+				},
+			},
+			want: &velerov1.Restore{
+				TypeMeta: metav1.TypeMeta{
+					APIVersion: "velero.io/v1",
+					Kind:       "Restore",
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "test-restore",
+				},
+				Spec: velerov1.RestoreSpec{
+					BackupName: "test-backup",
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetInstanceBackupRestore(tt.args.veleroBackup)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetInstanceBackupRestore() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetInstanceBackupRestore() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/kotsadmsnapshot/types/types.go b/pkg/kotsadmsnapshot/types/types.go
index 45c1eac11c..1c5b1a112e 100644
--- a/pkg/kotsadmsnapshot/types/types.go
+++ b/pkg/kotsadmsnapshot/types/types.go
@@ -16,6 +16,9 @@ const (
 	// InstanceBackupCountAnnotation is the annotation used to store the expected number of backups
 	// for an instance backup.
 	InstanceBackupCountAnnotation = "replicated.com/backup-count"
+	// InstanceBackupRestoreSpecAnnotation is the annotation used to store the corresponding restore
+	// spec for an instance backup.
+	InstanceBackupRestoreSpecAnnotation = "replicated.com/restore-spec"
 
 	// InstanceBackupTypeInfra indicates that the backup is of type infrastructure.
 	InstanceBackupTypeInfra = "infra"