diff --git a/lms/djangoapps/teams/csv.py b/lms/djangoapps/teams/csv.py
index 50e8ed412630aebecacef8b03f2d804fa6987ca3..0143253d21c48b3d4471798d334ecaab9b13410a 100644
--- a/lms/djangoapps/teams/csv.py
+++ b/lms/djangoapps/teams/csv.py
@@ -11,7 +11,8 @@ from django.db.models import Prefetch
 from lms.djangoapps.teams.api import (
     OrganizationProtectionStatus,
     user_organization_protection_status,
-    ORGANIZATION_PROTECTED_MODES
+    ORGANIZATION_PROTECTED_MODES,
+    user_protection_status_matches_team
 )
 from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
 from lms.djangoapps.program_enrollments.models import ProgramCourseEnrollment, ProgramEnrollment
@@ -359,6 +360,7 @@ class TeamMembershipImportManager(object):
         """
         Validates that only students enrolled in a masters track are on a single team. Disallows mixing of masters
         with other enrollment modes on a single team.
+        Masters track students can't be added to existing non-protected teams
         """
         if(teamset_id, team_name) not in self.user_enrollment_by_team:
             self.user_enrollment_by_team[teamset_id, team_name] = set()
@@ -368,8 +370,25 @@ class TeamMembershipImportManager(object):
                 'Team {} cannot have Master’s track users mixed with users in other tracks.'.format(team_name)
             self.add_error_and_check_if_max_exceeded(error_message)
             return False
+        if not self.is_enrollment_protection_for_existing_team_matches_user(user, team_name, teamset_id):
+            error_message = \
+                'User {} does not have access to team {}.'.format(user.username, team_name)
+            self.add_error_and_check_if_max_exceeded(error_message)
+            return False
         return True
 
+    def is_enrollment_protection_for_existing_team_matches_user(self, user, team_name, teamset_id):
+        """
+        Applies only to existing teams.
+        Returns True if no violations
+        False if there is a mismatch
+        """
+        try:
+            team = self.existing_course_teams[(team_name, teamset_id)]
+            return user_protection_status_matches_team(user, team)
+        except KeyError:
+            return True
+
     def is_FERPA_bubble_breached(self, teamset_id, team_name):
         """
         Ensures that FERPA bubble is not breached.
diff --git a/lms/djangoapps/teams/tests/test_views.py b/lms/djangoapps/teams/tests/test_views.py
index cc153862fb6c010999c6fc8c2f1f53bfe8bd5d7f..2526c14edf1399f7303fa9cd0d40b1c922095116 100644
--- a/lms/djangoapps/teams/tests/test_views.py
+++ b/lms/djangoapps/teams/tests/test_views.py
@@ -3077,3 +3077,29 @@ class TestBulkMembershipManagement(TeamAPITestCase):
             [user.username for user in team.users.all()],
             [user_name]
         )
+
+    def test_upload_assign_masters_learner_to_non_protected_team(self):
+        """
+        Scenario: Attempt to add a learner enrolled in masters track to an existing, non-org protected team.
+        Outcome: Must fail
+        """
+        masters_a = 'masters_a'
+        team = self.wind_team
+        self.create_and_enroll_student(username=masters_a, mode=CourseMode.MASTERS)
+        csv_content = 'user,mode,{}'.format(team.topic_id) + '\n'
+        csv_content += 'masters_a, masters,{}'.format(team.name)
+        csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
+        self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
+
+        response = self.make_call(
+            reverse('team_membership_bulk_management', args=[self.good_course_id]),
+            400, method='post',
+            data={'csv': csv_file},
+            user='staff'
+        )
+        response_text = json.loads(response.content.decode('utf-8'))
+        expected_message = 'User {} does not have access to team {}.'.format(
+            masters_a,
+            team.name
+        )
+        self.assertEqual(response_text['errors'][0], expected_message)