diff --git a/common/djangoapps/third_party_auth/pipeline.py b/common/djangoapps/third_party_auth/pipeline.py
index 84ecefabec3e6e115bdd8c64c3089b014f7a9e21..18924f21ce894694e8a90170eeaf69bc8839bc38 100644
--- a/common/djangoapps/third_party_auth/pipeline.py
+++ b/common/djangoapps/third_party_auth/pipeline.py
@@ -85,6 +85,7 @@ from edxmako.shortcuts import render_to_string
 from lms.djangoapps.verify_student.models import SSOVerification
 from lms.djangoapps.verify_student.utils import earliest_allowed_verification_date
 from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
+from openedx.core.djangoapps.user_api import accounts
 from openedx.core.djangoapps.user_authn import cookies as user_authn_cookies
 from third_party_auth.utils import user_exists
 from track import segment
@@ -850,7 +851,10 @@ def set_id_verification_status(auth_entry, strategy, details, user=None, *args,
 
 def get_username(strategy, details, backend, user=None, *args, **kwargs):
     """
-    Copy of social_core.pipeline.user.get_username with additional logging and case insensitive username checks.
+    Copy of social_core.pipeline.user.get_username to achieve
+    1. additional logging
+    2. case insensitive username checks
+    3. enforce same maximum and minimum length restrictions we have in `user_api/accounts`
     """
     if 'username' not in backend.setting('USER_FIELDS', USER_FIELDS):
         return
@@ -859,7 +863,8 @@ def get_username(strategy, details, backend, user=None, *args, **kwargs):
     if not user:
         email_as_username = strategy.setting('USERNAME_IS_FULL_EMAIL', False)
         uuid_length = strategy.setting('UUID_LENGTH', 16)
-        max_length = storage.user.username_max_length()
+        min_length = strategy.setting('USERNAME_MIN_LENGTH', accounts.USERNAME_MIN_LENGTH)
+        max_length = strategy.setting('USERNAME_MAX_LENGTH', accounts.USERNAME_MAX_LENGTH)
         do_slugify = strategy.setting('SLUGIFY_USERNAMES', False)
         do_clean = strategy.setting('CLEAN_USERNAMES', True)
 
@@ -898,7 +903,7 @@ def get_username(strategy, details, backend, user=None, *args, **kwargs):
         # username is cut to avoid any field max_length.
         # The final_username may be empty and will skip the loop.
         # We are using our own version of user_exists to avoid possible case sensitivity issues.
-        while not final_username or user_exists({'username': final_username}):
+        while not final_username or len(final_username) < min_length or user_exists({'username': final_username}):
             username = short_username + uuid4().hex[:uuid_length]
             final_username = slug_func(clean_func(username[:max_length]))
             logger.info(u'[THIRD_PARTY_AUTH] New username generated. Username: {username}'.format(
diff --git a/common/djangoapps/third_party_auth/settings.py b/common/djangoapps/third_party_auth/settings.py
index 0f6a4536c3f835e15b8a3d8f5fc93c191dc45ad5..b28f810df6d3fde52ec4b97bad440453b960eb3f 100644
--- a/common/djangoapps/third_party_auth/settings.py
+++ b/common/djangoapps/third_party_auth/settings.py
@@ -81,6 +81,9 @@ def apply_settings(django_settings):
     # enable this when you want to get stack traces rather than redirections.
     django_settings.SOCIAL_AUTH_RAISE_EXCEPTIONS = False
 
+    # Clean username to make sure username is compatible with our system requirements
+    django_settings.SOCIAL_AUTH_CLEAN_USERNAME_FUNCTION = 'third_party_auth.models.clean_username'
+
     # Allow users to login using social auth even if their account is not verified yet
     # This is required since we [ab]use django's 'is_active' flag to indicate verified
     # accounts; without this set to True, python-social-auth won't allow us to link the
diff --git a/common/djangoapps/third_party_auth/tests/test_pipeline.py b/common/djangoapps/third_party_auth/tests/test_pipeline.py
index 2374c4827e7d4fd819b828ba8d65c6f50f00ba1f..9613706cf65d1a5a78154668856f40bc2d333817 100644
--- a/common/djangoapps/third_party_auth/tests/test_pipeline.py
+++ b/common/djangoapps/third_party_auth/tests/test_pipeline.py
@@ -9,6 +9,8 @@ import mock
 
 from third_party_auth import pipeline
 from third_party_auth.tests import testutil
+from third_party_auth.tests.specs.base import IntegrationTestMixin
+from third_party_auth.tests.specs.test_testshib import SamlIntegrationTestUtilities
 from third_party_auth.tests.testutil import simulate_running_pipeline
 
 
@@ -50,3 +52,49 @@ class ProviderUserStateTestCase(testutil.TestCase):
         with simulate_running_pipeline("third_party_auth.pipeline", backend_name, **kwargs):
             logout_url = pipeline.get_idp_logout_url_from_running_pipeline(request)
             self.assertEqual(idp_config['logout_url'], logout_url)
+
+
+@unittest.skipUnless(testutil.AUTH_FEATURE_ENABLED, testutil.AUTH_FEATURES_KEY + ' not enabled')
+@ddt.ddt
+class PipelineOverridesTest(SamlIntegrationTestUtilities, IntegrationTestMixin, testutil.SAMLTestCase):
+    """
+    Tests for pipeline overrides
+    """
+
+    def setUp(self):
+        super(PipelineOverridesTest, self).setUp()
+        self.enable_saml()
+        self.provider = self.configure_saml_provider(
+            enabled=True,
+            name="Test Provider",
+            slug='test',
+            backend_name='tpa-saml'
+        )
+
+    @ddt.data(
+        ('S', 'S9fe2', False),
+        ('S', 'S9fe2', True),
+        ('S.K', 'S_K', False),
+        ('S.K.', 'S_K_', False),
+        ('S.K.', 'S_K_9fe2', True),
+        ('usernamewithcharacterlengthofmorethan30chars', 'usernamewithcharacterlengthofm', False),
+        ('usernamewithcharacterlengthofmorethan30chars', 'usernamewithcharacterlengt9fe2', True),
+    )
+    @ddt.unpack
+    @mock.patch('third_party_auth.pipeline.user_exists')
+    def test_get_username_in_pipeline(self, idp_username, expected_username, already_exists, mock_user_exists):
+        """
+        Test get_username method of running pipeline
+        """
+        details = {
+            "username": idp_username,
+            "email": "test@example.com"
+        }
+        mock_user_exists.side_effect = [already_exists, False]
+        __, strategy = self.get_request_and_strategy()
+        with mock.patch('third_party_auth.pipeline.uuid4') as mock_uuid:
+            uuid4 = mock.Mock()
+            type(uuid4).hex = mock.PropertyMock(return_value='9fe2c4e93f654fdbb24c02b15259716c')
+            mock_uuid.return_value = uuid4
+            final_username = pipeline.get_username(strategy, details, self.provider.backend_class())
+            self.assertEqual(expected_username, final_username['username'])