diff --git a/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/jsonapi_test_auth_exception.info.yml b/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/jsonapi_test_auth_exception.info.yml
new file mode 100644
index 0000000000..996d17b6ea
--- /dev/null
+++ b/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/jsonapi_test_auth_exception.info.yml
@@ -0,0 +1,4 @@
+name: 'JSON API test auth exception'
+type: module
+description: 'Provides an authorization exception provider to test JSON:API authorization.'
+package: Testing
diff --git a/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/jsonapi_test_auth_exception.services.yml b/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/jsonapi_test_auth_exception.services.yml
new file mode 100644
index 0000000000..13ed2e7e74
--- /dev/null
+++ b/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/jsonapi_test_auth_exception.services.yml
@@ -0,0 +1,6 @@
+services:
+  jsonapi_test_auth_exception.authentication.simple_oauth:
+    class: Drupal\jsonapi_test_auth_exception\Authentication\Provider\AuthenticationWithExceptionProvider
+    arguments: {}
+    tags:
+      - { name: authentication_provider, provider_id: jsonapi_test_auth_exception, global: TRUE, priority: 35 }
diff --git a/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/src/Authentication/Provider/AuthenticationWithExceptionProvider.php b/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/src/Authentication/Provider/AuthenticationWithExceptionProvider.php
new file mode 100644
index 0000000000..ab56c23d16
--- /dev/null
+++ b/core/modules/jsonapi/tests/modules/jsonapi_test_auth_exception/src/Authentication/Provider/AuthenticationWithExceptionProvider.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\jsonapi_test_auth_exception\Authentication\Provider;
+
+use Drupal\Core\Authentication\AuthenticationProviderInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+
+/**
+ * An authentication provider that throws an auth exception when requested.
+ *
+ * To request an auth exception pass a "Authorization: Bearer exception"
+ * header.
+ */
+class AuthenticationWithExceptionProvider implements AuthenticationProviderInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Request $request) {
+    if (!$request->headers->has('Authorization')) {
+      return FALSE;
+    }
+    if ('Bearer exception' == $request->headers->get('Authorization')) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function authenticate(Request $request) {
+    throw new HttpException(
+      401,
+      'An auth exception was requested.'
+    );
+  }
+
+}
diff --git a/core/modules/jsonapi/tests/src/Functional/RestJsonApiAuthException.php b/core/modules/jsonapi/tests/src/Functional/RestJsonApiAuthException.php
new file mode 100644
index 0000000000..6955186e4c
--- /dev/null
+++ b/core/modules/jsonapi/tests/src/Functional/RestJsonApiAuthException.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Drupal\Tests\jsonapi\Functional;
+
+use Drupal\Core\Url;
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\ResourceTestBase;
+use GuzzleHttp\RequestOptions;
+
+/**
+ * Ensures that the 'api_json' format is used even on auth exception.
+ *
+ * @group jsonapi
+ *
+ * @internal
+ */
+class RestJsonApiAuthException extends ResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'jsonapi',
+    'node',
+    'user',
+    'jsonapi_test_user',
+    'jsonapi_test_auth_exception',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'api_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/vnd.api+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $resourceConfigId = 'entity.node';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpAuthorization($method) {
+    // @todo Remove this in
+    $this->grantPermissionsToTestedRole(['access content']);
+
+    switch ($method) {
+      case 'GET':
+        $this->grantPermissionsToTestedRole(['access user profiles']);
+        break;
+
+      case 'POST':
+      case 'PATCH':
+      case 'DELETE':
+        $this->grantPermissionsToTestedRole(['administer users']);
+        break;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp(): void {
+    parent::setUp();
+
+    // Set up a HTTP client that accepts relative URLs.
+    $this->httpClient = $this->container->get('http_client_factory')
+      ->fromOptions(['base_uri' => $this->baseUrl]);
+  }
+
+  /**
+   * An auth exception to a JSON API route results in a JSON API response.
+   *
+   * @see \Drupal\jsonapi\EventSubscriber\JsonApiRequestValidator::validateQueryParams()
+   */
+  public function testApiJsonAuthExceptionIsJson() {
+    $user = $this->setUpCurrentUser();
+    $this->assertSame(['json', 'xml'], $this->container->getParameter('serializer.formats'));
+
+    $this->provisionResource(['api_json'], []);
+    $this->setUpAuthorization('GET');
+
+    $url = Url::fromRoute(sprintf('jsonapi.user--user.individual'), ['entity' => $user->uuid()]);
+    $request_options = [
+      RequestOptions::HEADERS => [
+        'Authorization' => 'Bearer exception',
+        'Cache-Control' => 'no-cache',
+      ],
+    ];
+    $response = $this->request('GET', $url, $request_options);
+
+    $this->assertResourceErrorResponse(
+      401,
+      FALSE,
+      $response,
+      ['4xx-response', 'http_response'],
+      ['url.site'],
+      'MISS',
+      'UNCACHEABLE'
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertNormalizationEdgeCases($method, Url $url, array $request_options) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedUnauthorizedAccessMessage($method) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedUnauthorizedAccessCacheability() {}
+
+}
