diff --git a/app/assets/javascripts/projects/settings/components/default_branch_selector.vue b/app/assets/javascripts/projects/settings/components/default_branch_selector.vue
index f5fb72e84bc5157676836578e9cb00690f5217d5..d1c143b96f7749a1424db2f211610fbc1e86f868 100644
--- a/app/assets/javascripts/projects/settings/components/default_branch_selector.vue
+++ b/app/assets/javascripts/projects/settings/components/default_branch_selector.vue
@@ -8,6 +8,11 @@ export default {
     RefSelector,
   },
   props: {
+    disabled: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
     persistedDefaultBranch: {
       type: String,
       required: true,
@@ -26,6 +31,7 @@ export default {
 </script>
 <template>
   <ref-selector
+    :disabled="disabled"
     :value="persistedDefaultBranch"
     class="gl-w-full"
     :project-id="projectId"
diff --git a/app/assets/javascripts/projects/settings/mount_default_branch_selector.js b/app/assets/javascripts/projects/settings/mount_default_branch_selector.js
index 611561e38f2e0dbd923ab61bc00e28f65a13b3d0..8e64d29e947ea779677bbeb01ad4753bce303704 100644
--- a/app/assets/javascripts/projects/settings/mount_default_branch_selector.js
+++ b/app/assets/javascripts/projects/settings/mount_default_branch_selector.js
@@ -1,4 +1,5 @@
 import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
 import DefaultBranchSelector from './components/default_branch_selector.vue';
 
 export default (el) => {
@@ -6,13 +7,14 @@ export default (el) => {
     return null;
   }
 
-  const { projectId, defaultBranch } = el.dataset;
+  const { projectId, defaultBranch, disabled } = el.dataset;
 
   return new Vue({
     el,
     render(createElement) {
       return createElement(DefaultBranchSelector, {
         props: {
+          disabled: parseBoolean(disabled),
           persistedDefaultBranch: defaultBranch,
           projectId,
         },
diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue
index ed9fd521e67bcb23ece7389c236687c9a4f39b33..0d6b19829f217fe9412cd881beca793ce61bc303 100644
--- a/app/assets/javascripts/ref/components/ref_selector.vue
+++ b/app/assets/javascripts/ref/components/ref_selector.vue
@@ -28,12 +28,17 @@ export default {
   },
   inheritAttrs: false,
   props: {
+    disabled: {
+      type: Boolean,
+      required: false,
+      default: false,
+    },
     enabledRefTypes: {
       type: Array,
       required: false,
       default: () => ALL_REF_TYPES,
       validator: (val) =>
-        // It has to be an arrray
+        // It has to be an array
         isArray(val) &&
         // with at least one item
         val.length > 0 &&
@@ -234,6 +239,10 @@ export default {
       this.debouncedSearch();
     },
     selectRef(ref) {
+      if (this.disabled) {
+        return;
+      }
+
       this.setSelectedRef(ref);
       this.$emit('input', this.selectedRef);
     },
@@ -262,6 +271,7 @@ export default {
       :toggle-class="extendedToggleButtonClass"
       :toggle-text="buttonText"
       :icon="dropdownIcon"
+      :disabled="disabled"
       v-bind="$attrs"
       v-on="$listeners"
       @hidden="$emit('hide')"
diff --git a/app/views/projects/branch_defaults/_default_branch_fields.html.haml b/app/views/projects/branch_defaults/_default_branch_fields.html.haml
index 78ce43ca8c9e579eb2254ed6aeb49efd4e63a175..f3a7e93a5f7ee7455eeb107d43c48f756be58be7 100644
--- a/app/views/projects/branch_defaults/_default_branch_fields.html.haml
+++ b/app/views/projects/branch_defaults/_default_branch_fields.html.haml
@@ -1,3 +1,13 @@
+- change_default_disabled = @default_branch_blocked_by_security_policy
+- popover_data = {}
+
+- if change_default_disabled
+  - tag_pair_security_policies_page = tag_pair(link_to('', namespace_project_security_policies_path, target: '_blank', rel: 'noopener noreferrer'), :security_policies_link_start, :security_policies_link_end)
+  - tag_pair_security_policies_docs = tag_pair(link_to('', help_page_path('user/application_security/policies/scan-result-policies'), target: '_blank', rel: 'noopener noreferrer'), :learn_more_link_start, :learn_more_link_end)
+  - popover_content = safe_format(s_("SecurityOrchestration|You can't change the default branch because its protection is enforced by one or more %{security_policies_link_start}security policies%{security_policies_link_end}. %{learn_more_link_start}Learn more%{learn_more_link_end}."), tag_pair_security_policies_docs, tag_pair_security_policies_page)
+  - popover_title = s_("SecurityOrchestration|Security policy overwrites this setting")
+  - popover_data = { container: 'body', toggle: 'popover', html: 'true', triggers: 'hover', title: popover_title, content: popover_content }
+
 %fieldset#default-branch-settings
   - if @project.empty_repo?
     .text-secondary
@@ -6,8 +16,8 @@
     .form-group
       = f.label :default_branch, _("Default branch"), class: 'label-bold'
       %p= s_('ProjectSettings|All merge requests and commits are made against this branch unless you specify a different one.')
-      .gl-form-input-xl
-        .js-select-default-branch{ data: { default_branch: @project.default_branch, project_id: @project.id } }
+      .gl-form-input-xl{ data: { **popover_data } }
+        .js-select-default-branch{ data: { default_branch: @project.default_branch, project_id: @project.id, disabled: change_default_disabled.to_s } }
 
   .form-group
     - help_text = _("When merge requests and commits in the default branch close, any issues they reference also close.")
diff --git a/ee/spec/features/projects/settings/user_changes_default_branch_spec.rb b/ee/spec/features/projects/settings/user_changes_default_branch_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ab526049b094d407de746f18f9c69f7a5ff875a4
--- /dev/null
+++ b/ee/spec/features/projects/settings/user_changes_default_branch_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Settings > User changes default branch', feature_category: :groups_and_projects do
+  let_it_be(:user) { create(:user) }
+  let_it_be(:project) { create(:project, :repository, namespace: user.namespace) }
+  let_it_be(:protected_branch) { create(:protected_branch, project: project, name: project.default_branch) }
+  let(:default_branch_settings) { find('#default-branch-settings') }
+  let(:default_branch_button) do
+    within_testid('default-branch-dropdown') do
+      find('button')
+    end
+  end
+
+  let(:visit_repository_page) { visit project_settings_repository_path(project) }
+
+  before do
+    sign_in(user)
+  end
+
+  context 'with branch not protected by security policy' do
+    it 'does not show popover if the default branch can be changed', :aggregate_failures, :js do
+      visit_repository_page
+
+      expect(default_branch_settings).not_to have_selector('[data-toggle="popover"]')
+      expect(default_branch_button).not_to be_disabled
+    end
+  end
+
+  context 'with branch protected by security policy' do
+    include_context 'with scan result policy blocking protected branches' do
+      let(:branch_name) { project.default_branch }
+      let(:policy_configuration) do
+        create(:security_orchestration_policy_configuration, project: project)
+      end
+
+      it 'disables the button and shows the popover if the default branch cannot be changed',
+        :aggregate_failures,
+        :js do
+        visit_repository_page
+
+        expect(default_branch_settings).to have_selector('[data-toggle="popover"]')
+        expect(default_branch_button).to be_disabled
+      end
+    end
+  end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index fea46aac1bc46f2c290c4049b2c4231f80f69951..0f27d1e1966d7d16d3b760eacadb92930c9694d6 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -43291,6 +43291,9 @@ msgstr ""
 msgid "SecurityOrchestration|Security Scan"
 msgstr ""
 
+msgid "SecurityOrchestration|Security policy overwrites this setting"
+msgstr ""
+
 msgid "SecurityOrchestration|Security policy project was linked successfully"
 msgstr ""
 
@@ -43441,6 +43444,9 @@ msgstr ""
 msgid "SecurityOrchestration|You already have the maximum %{maximumAllowed} %{policyType} policies."
 msgstr ""
 
+msgid "SecurityOrchestration|You can't change the default branch because its protection is enforced by one or more %{security_policies_link_start}security policies%{security_policies_link_end}. %{learn_more_link_start}Learn more%{learn_more_link_end}."
+msgstr ""
+
 msgid "SecurityOrchestration|You can't unprotect this branch because its protection is enforced by one or more %{security_policies_link_start}security policies%{security_policies_link_end}. %{learn_more_link_start}Learn more%{learn_more_link_end}."
 msgstr ""
 
diff --git a/spec/frontend/projects/settings/components/default_branch_selector_spec.js b/spec/frontend/projects/settings/components/default_branch_selector_spec.js
index 9baea5c5517a7ed3531343b1ab7cc12dad9bb132..aa50683b1851e0a7059eae41009f47778b08a425 100644
--- a/spec/frontend/projects/settings/components/default_branch_selector_spec.js
+++ b/spec/frontend/projects/settings/components/default_branch_selector_spec.js
@@ -4,6 +4,7 @@ import RefSelector from '~/ref/components/ref_selector.vue';
 import { REF_TYPE_BRANCHES } from '~/ref/constants';
 
 describe('projects/settings/components/default_branch_selector', () => {
+  const disabled = true;
   const persistedDefaultBranch = 'main';
   const projectId = '123';
   let wrapper;
@@ -13,6 +14,7 @@ describe('projects/settings/components/default_branch_selector', () => {
   const buildWrapper = () => {
     wrapper = shallowMount(DefaultBranchSelector, {
       propsData: {
+        disabled,
         persistedDefaultBranch,
         projectId,
       },
@@ -25,6 +27,7 @@ describe('projects/settings/components/default_branch_selector', () => {
 
   it('displays a RefSelector component', () => {
     expect(findRefSelector().props()).toEqual({
+      disabled,
       value: persistedDefaultBranch,
       enabledRefTypes: [REF_TYPE_BRANCHES],
       projectId,
diff --git a/spec/frontend/ref/components/ref_selector_spec.js b/spec/frontend/ref/components/ref_selector_spec.js
index 26010a1cfa6545462725ac6a8d809e2a1ab4c90a..39924a3a77af1a86ab9a176d65a58a663a8cee30 100644
--- a/spec/frontend/ref/components/ref_selector_spec.js
+++ b/spec/frontend/ref/components/ref_selector_spec.js
@@ -46,7 +46,7 @@ describe('Ref selector component', () => {
   let commitApiCallSpy;
   let requestSpies;
 
-  const createComponent = (mountOverrides = {}, propsData = {}) => {
+  const createComponent = ({ overrides = {}, propsData = {} } = {}) => {
     wrapper = mountExtended(
       RefSelector,
       merge(
@@ -64,7 +64,7 @@ describe('Ref selector component', () => {
           },
           store: createStore(),
         },
-        mountOverrides,
+        overrides,
       ),
     );
   };
@@ -211,7 +211,7 @@ describe('Ref selector component', () => {
       const id = 'git-ref';
 
       beforeEach(() => {
-        createComponent({ attrs: { id } });
+        createComponent({ overrides: { attrs: { id } } });
 
         return waitForRequests();
       });
@@ -326,7 +326,7 @@ describe('Ref selector component', () => {
     describe('branches', () => {
       describe('when the branches search returns results', () => {
         beforeEach(() => {
-          createComponent({}, { useSymbolicRefNames: true });
+          createComponent({ propsData: { useSymbolicRefNames: true } });
 
           return waitForRequests();
         });
@@ -389,7 +389,7 @@ describe('Ref selector component', () => {
     describe('tags', () => {
       describe('when the tags search returns results', () => {
         beforeEach(() => {
-          createComponent({}, { useSymbolicRefNames: true });
+          createComponent({ propsData: { useSymbolicRefNames: true } });
 
           return waitForRequests();
         });
@@ -569,6 +569,20 @@ describe('Ref selector component', () => {
         });
       });
     });
+
+    describe('disabled', () => {
+      it('does not disable the dropdown', () => {
+        createComponent();
+        expect(findListbox().props('disabled')).toBe(false);
+      });
+
+      it('disables the dropdown', async () => {
+        createComponent({ propsData: { disabled: true } });
+        expect(findListbox().props('disabled')).toBe(true);
+        await selectFirstBranch();
+        expect(wrapper.emitted('input')).toBeUndefined();
+      });
+    });
   });
 
   describe('with non-default ref types', () => {
@@ -691,9 +705,7 @@ describe('Ref selector component', () => {
     });
 
     beforeEach(() => {
-      createComponent({
-        scopedSlots: { footer: createFooter },
-      });
+      createComponent({ overrides: { scopedSlots: { footer: createFooter } } });
 
       updateQuery('abcd1234');