diff --git a/changelogs/unreleased/3877-zubron b/changelogs/unreleased/3877-zubron
new file mode 100644
index 000000000..c4020a4bc
--- /dev/null
+++ b/changelogs/unreleased/3877-zubron
@@ -0,0 +1 @@
+Skip the restore of volumes that originally came from a projected volume when using restic.
\ No newline at end of file
diff --git a/pkg/restic/common.go b/pkg/restic/common.go
index 5ce15e32e..e122ff4bb 100644
--- a/pkg/restic/common.go
+++ b/pkg/restic/common.go
@@ -100,9 +100,20 @@ func isPVBMatchPod(pvb *velerov1api.PodVolumeBackup, podName string, namespace s
 	return podName == pvb.Spec.Pod.Name && namespace == pvb.Spec.Pod.Namespace
 }
 
+// volumeIsProjected checks if the given volume exists in the list of podVolumes
+// and returns true if the volume has a projected source
+func volumeIsProjected(volumeName string, podVolumes []corev1api.Volume) bool {
+	for _, volume := range podVolumes {
+		if volume.Name == volumeName && volume.Projected != nil {
+			return true
+		}
+	}
+	return false
+}
+
 // GetVolumeBackupsForPod returns a map, of volume name -> snapshot id,
 // of the PodVolumeBackups that exist for the provided pod.
-func GetVolumeBackupsForPod(podVolumeBackups []*velerov1api.PodVolumeBackup, pod metav1.Object, sourcePodNs string) map[string]string {
+func GetVolumeBackupsForPod(podVolumeBackups []*velerov1api.PodVolumeBackup, pod *corev1api.Pod, sourcePodNs string) map[string]string {
 	volumes := make(map[string]string)
 
 	for _, pvb := range podVolumeBackups {
@@ -116,6 +127,13 @@ func GetVolumeBackupsForPod(podVolumeBackups []*velerov1api.PodVolumeBackup, pod
 			continue
 		}
 
+		// If the volume came from a projected source, skip its restore.
+		// This allows backups affected by https://github.com/vmware-tanzu/velero/issues/3863
+		// to be restored successfully.
+		if volumeIsProjected(pvb.Spec.Volume, pod.Spec.Volumes) {
+			continue
+		}
+
 		volumes[pvb.Spec.Volume] = pvb.Status.SnapshotID
 	}
 
diff --git a/pkg/restic/common_test.go b/pkg/restic/common_test.go
index b5e0f1ff9..7e102ca97 100644
--- a/pkg/restic/common_test.go
+++ b/pkg/restic/common_test.go
@@ -37,6 +37,7 @@ func TestGetVolumeBackupsForPod(t *testing.T) {
 	tests := []struct {
 		name             string
 		podVolumeBackups []*velerov1api.PodVolumeBackup
+		podVolumes       []corev1api.Volume
 		podAnnotations   map[string]string
 		podName          string
 		sourcePodNs      string
@@ -127,6 +128,30 @@ func TestGetVolumeBackupsForPod(t *testing.T) {
 			sourcePodNs: "TestNS",
 			expected:    map[string]string{"pvbtest1-foo": "snapshot1"},
 		},
+		{
+			name: "volumes from PVBs that correspond to a pod volume from a projected source are not returned",
+			podVolumeBackups: []*velerov1api.PodVolumeBackup{
+				builder.ForPodVolumeBackup("velero", "pvb-1").PodName("TestPod").PodNamespace("TestNS").SnapshotID("snapshot1").Volume("pvb-non-projected").Result(),
+				builder.ForPodVolumeBackup("velero", "pvb-1").PodName("TestPod").PodNamespace("TestNS").SnapshotID("snapshot2").Volume("pvb-projected").Result(),
+			},
+			podVolumes: []corev1api.Volume{
+				{
+					Name: "pvb-non-projected",
+					VolumeSource: corev1api.VolumeSource{
+						PersistentVolumeClaim: &corev1api.PersistentVolumeClaimVolumeSource{},
+					},
+				},
+				{
+					Name: "pvb-projected",
+					VolumeSource: corev1api.VolumeSource{
+						Projected: &corev1api.ProjectedVolumeSource{},
+					},
+				},
+			},
+			podName:     "TestPod",
+			sourcePodNs: "TestNS",
+			expected:    map[string]string{"pvb-non-projected": "snapshot1"},
+		},
 	}
 
 	for _, test := range tests {
@@ -134,6 +159,7 @@ func TestGetVolumeBackupsForPod(t *testing.T) {
 			pod := &corev1api.Pod{}
 			pod.Annotations = test.podAnnotations
 			pod.Name = test.podName
+			pod.Spec.Volumes = test.podVolumes
 
 			res := GetVolumeBackupsForPod(test.podVolumeBackups, pod, test.sourcePodNs)
 			assert.Equal(t, test.expected, res)
@@ -629,3 +655,78 @@ func TestIsPVBMatchPod(t *testing.T) {
 
 	}
 }
+
+func TestVolumeIsProjected(t *testing.T) {
+	testCases := []struct {
+		name       string
+		volumeName string
+		podVolumes []corev1api.Volume
+		expected   bool
+	}{
+		{
+			name:       "volume name not in list of volumes",
+			volumeName: "missing-volume",
+			podVolumes: []corev1api.Volume{
+				{
+					Name: "non-projected",
+					VolumeSource: corev1api.VolumeSource{
+						PersistentVolumeClaim: &corev1api.PersistentVolumeClaimVolumeSource{},
+					},
+				},
+				{
+					Name: "projected",
+					VolumeSource: corev1api.VolumeSource{
+						Projected: &corev1api.ProjectedVolumeSource{},
+					},
+				},
+			},
+			expected: false,
+		},
+		{
+			name:       "volume name in list of volumes but not projected",
+			volumeName: "non-projected",
+			podVolumes: []corev1api.Volume{
+				{
+					Name: "non-projected",
+					VolumeSource: corev1api.VolumeSource{
+						PersistentVolumeClaim: &corev1api.PersistentVolumeClaimVolumeSource{},
+					},
+				},
+				{
+					Name: "projected",
+					VolumeSource: corev1api.VolumeSource{
+						Projected: &corev1api.ProjectedVolumeSource{},
+					},
+				},
+			},
+			expected: false,
+		},
+		{
+			name:       "volume name in list of volumes and projected",
+			volumeName: "projected",
+			podVolumes: []corev1api.Volume{
+				{
+					Name: "non-projected",
+					VolumeSource: corev1api.VolumeSource{
+						PersistentVolumeClaim: &corev1api.PersistentVolumeClaimVolumeSource{},
+					},
+				},
+				{
+					Name: "projected",
+					VolumeSource: corev1api.VolumeSource{
+						Projected: &corev1api.ProjectedVolumeSource{},
+					},
+				},
+			},
+			expected: true,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			actual := volumeIsProjected(tc.volumeName, tc.podVolumes)
+			assert.Equal(t, tc.expected, actual)
+		})
+
+	}
+}
diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go
index 4817dca38..41aee1938 100644
--- a/pkg/restore/restore.go
+++ b/pkg/restore/restore.go
@@ -1232,8 +1232,16 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso
 		return warnings, errs
 	}
 
-	if groupResource == kuberesource.Pods && len(restic.GetVolumeBackupsForPod(ctx.podVolumeBackups, obj, originalNamespace)) > 0 {
-		restorePodVolumeBackups(ctx, createdObj, originalNamespace)
+	if groupResource == kuberesource.Pods {
+		pod := new(v1.Pod)
+		if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), pod); err != nil {
+			errs.Add(namespace, err)
+			return warnings, errs
+		}
+
+		if len(restic.GetVolumeBackupsForPod(ctx.podVolumeBackups, pod, originalNamespace)) > 0 {
+			restorePodVolumeBackups(ctx, createdObj, originalNamespace)
+		}
 	}
 
 	if groupResource == kuberesource.Pods {