diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 058c35fc2b0df096967082645f1092ac071f9379..28fdd674aa45c4a703ee3d0e61c4ae2567ba6de1 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -197,7 +197,11 @@ class CommitStatus < Ci::ApplicationRecord
 
       commit_status.failure_reason = reason.failure_reason_enum
       commit_status.allow_failure = true if reason.force_allow_failure?
-      commit_status.exit_code = reason.exit_code if Feature.enabled?(:ci_retry_on_exit_codes, Feature.current_request)
+      # Windows exit codes can reach a max value of 32-bit unsigned integer
+      # We only allow a smallint for exit_code in the db, hence the added limit of 32767
+      if reason.exit_code && Feature.enabled?(:ci_retry_on_exit_codes, Feature.current_request)
+        commit_status.exit_code = reason.exit_code % 32768
+      end
     end
 
     before_transition [:skipped, :manual] => :created do |commit_status, transition|
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index f5f29109c10bf8b068f3e104b4d376df8eb001de..72b59d848210e3f50ae64aefc0cfcff4869cbd0b 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -5257,6 +5257,15 @@ def run_job_without_exception
         end
       end
     end
+
+    context 'when exit code is greater than 32767' do
+      let(:exit_code) { 32770 }
+
+      it 'wraps around to max size of a signed smallint' do
+        expect { drop_with_exit_code }
+        .to change { build.reload.metadata&.exit_code }.from(nil).to(2)
+      end
+    end
   end
 
   describe '#exit_codes_defined?' do