diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb
index 35be549305..4339bee21e 100644
--- a/app/controllers/api/v2/search_controller.rb
+++ b/app/controllers/api/v2/search_controller.rb
@@ -8,6 +8,11 @@ class Api::V2::SearchController < Api::BaseController
   before_action -> { authorize_if_got_token! :read, :'read:search' }
   before_action :validate_search_params!
 
+  with_options unless: :user_signed_in? do
+    before_action :query_pagination_error, if: :pagination_requested?
+    before_action :remote_resolve_error, if: :remote_resolve_requested?
+  end
+
   def index
     @search = Search.new(search_results)
     render json: @search, serializer: REST::SearchSerializer
@@ -21,12 +26,22 @@ class Api::V2::SearchController < Api::BaseController
 
   def validate_search_params!
     params.require(:q)
+  end
 
-    return if user_signed_in?
+  def query_pagination_error
+    render json: { error: 'Search queries pagination is not supported without authentication' }, status: 401
+  end
 
-    return render json: { error: 'Search queries pagination is not supported without authentication' }, status: 401 if params[:offset].present?
+  def remote_resolve_error
+    render json: { error: 'Search queries that resolve remote resources are not supported without authentication' }, status: 401
+  end
 
-    render json: { error: 'Search queries that resolve remote resources are not supported without authentication' }, status: 401 if truthy_param?(:resolve)
+  def remote_resolve_requested?
+    truthy_param?(:resolve)
+  end
+
+  def pagination_requested?
+    params[:offset].present?
   end
 
   def search_results
@@ -34,7 +49,15 @@ class Api::V2::SearchController < Api::BaseController
       params[:q],
       current_account,
       limit_param(RESULTS_LIMIT),
-      search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed), following: truthy_param?(:following))
+      combined_search_params
+    )
+  end
+
+  def combined_search_params
+    search_params.merge(
+      resolve: truthy_param?(:resolve),
+      exclude_unreviewed: truthy_param?(:exclude_unreviewed),
+      following: truthy_param?(:following)
     )
   end
 
diff --git a/spec/controllers/api/v2/search_controller_spec.rb b/spec/controllers/api/v2/search_controller_spec.rb
index d3ff42d6a0..a16716a10c 100644
--- a/spec/controllers/api/v2/search_controller_spec.rb
+++ b/spec/controllers/api/v2/search_controller_spec.rb
@@ -34,6 +34,26 @@ RSpec.describe Api::V2::SearchController do
           expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(bob.id.to_s, ana.id.to_s, tom.id.to_s)
         end
 
+        context 'with truthy `resolve`' do
+          let(:params) { { q: 'test1', resolve: '1' } }
+
+          it 'returns http unauthorized' do
+            get :index, params: params
+
+            expect(response).to have_http_status(200)
+          end
+        end
+
+        context 'with `offset`' do
+          let(:params) { { q: 'test1', offset: 1 } }
+
+          it 'returns http unauthorized' do
+            get :index, params: params
+
+            expect(response).to have_http_status(200)
+          end
+        end
+
         context 'with following=true' do
           let(:params) { { q: 'test', type: 'accounts', following: 'true' } }
 
@@ -48,6 +68,26 @@ RSpec.describe Api::V2::SearchController do
           end
         end
       end
+
+      context 'when search raises syntax error' do
+        before { allow(Search).to receive(:new).and_raise(Mastodon::SyntaxError) }
+
+        it 'returns http unprocessable_entity' do
+          get :index, params: params
+
+          expect(response).to have_http_status(422)
+        end
+      end
+
+      context 'when search raises not found error' do
+        before { allow(Search).to receive(:new).and_raise(ActiveRecord::RecordNotFound) }
+
+        it 'returns http not_found' do
+          get :index, params: params
+
+          expect(response).to have_http_status(404)
+        end
+      end
     end
   end
 
@@ -59,6 +99,12 @@ RSpec.describe Api::V2::SearchController do
         get :index, params: search_params
       end
 
+      context 'without a `q` param' do
+        it 'returns http bad_request' do
+          expect(response).to have_http_status(400)
+        end
+      end
+
       context 'with a `q` shorter than 5 characters' do
         let(:search_params) { { q: 'test' } }
 
@@ -79,6 +125,7 @@ RSpec.describe Api::V2::SearchController do
 
           it 'returns http unauthorized' do
             expect(response).to have_http_status(401)
+            expect(response.body).to match('resolve remote resources')
           end
         end
 
@@ -87,6 +134,7 @@ RSpec.describe Api::V2::SearchController do
 
           it 'returns http unauthorized' do
             expect(response).to have_http_status(401)
+            expect(response.body).to match('pagination is not supported')
           end
         end
       end