diff --git a/src/Authenticator/BearerUserProvider.php b/src/Authenticator/BearerUserProvider.php
index c0656f1aae2c7ee24cc76b365e86cea840483419..e209d48b8b230ad105e0adf38dfc42e8fd8777e8 100644
--- a/src/Authenticator/BearerUserProvider.php
+++ b/src/Authenticator/BearerUserProvider.php
@@ -38,10 +38,15 @@ class BearerUserProvider implements BearerUserProviderInterface, LoggerAwareInte
         return $config['local_validation_leeway'];
     }
 
+    public function usesRemoteValidation(): bool
+    {
+        return $this->config['remote_validation'];
+    }
+
     public function loadUserByToken(string $accessToken): UserInterface
     {
         $config = $this->config;
-        if (!$config['remote_validation']) {
+        if (!$this->usesRemoteValidation()) {
             $leeway = $config['local_validation_leeway'];
             $validator = new LocalTokenValidator($this->oidProvider, $leeway);
         } else {
diff --git a/src/OIDC/OIDProvider.php b/src/OIDC/OIDProvider.php
index fd961f8d209a0fca76d66b23fc0f90f661569a3d..040ba1975b578156747423116986eb18421385ac 100644
--- a/src/OIDC/OIDProvider.php
+++ b/src/OIDC/OIDProvider.php
@@ -138,6 +138,49 @@ class OIDProvider implements LoggerAwareInterface
         return $jwks;
     }
 
+    /**
+     * This creates a token using the introspection client. Mainly for testing
+     * introspection during health checks.
+     */
+    public function createToken(): string
+    {
+        $providerConfig = $this->getProviderConfig();
+        $tokenEndpoint = $providerConfig->getTokenEndpoint();
+        if ($tokenEndpoint === null) {
+            throw new OIDError('No token endpoint');
+        }
+
+        $authId = $this->config['remote_validation_id'] ?? '';
+        $authSecret = $this->config['remote_validation_secret'] ?? '';
+        if ($authId === '' || $authSecret === '') {
+            throw new OIDError('remote_validation_id/secret not set');
+        }
+
+        $client = $this->getClient();
+
+        try {
+            // keep in mind that even if we are doing this request with a different client id the data returned will be
+            // from the client id of token $token (that's important for mapped attributes)
+            $response = $client->request('POST', $tokenEndpoint, [
+                'auth' => [$authId, $authSecret],
+                'form_params' => [
+                    'grant_type' => 'client_credentials',
+                ],
+            ]);
+        } catch (GuzzleException $e) {
+            throw new OIDError('Creating a token failed: '.$e->getMessage());
+        }
+
+        $data = (string) $response->getBody();
+        try {
+            $decoded = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
+        } catch (\JsonException $e) {
+            throw new OIDError('Token: invalid json: '.$e->getMessage());
+        }
+
+        return $decoded['access_token'];
+    }
+
     /**
      * Introspect the token via the provider. Note that you have to check the result to see if the
      * token is valid/active.
diff --git a/src/OIDC/OIDProviderConfig.php b/src/OIDC/OIDProviderConfig.php
index 8f1602fd541d1c843fb5c62e8fd92f2d14755e43..805793f5d61b7da97333455c1e886f575d7d284a 100644
--- a/src/OIDC/OIDProviderConfig.php
+++ b/src/OIDC/OIDProviderConfig.php
@@ -42,6 +42,11 @@ class OIDProviderConfig
         return $this->config['jwks_uri'];
     }
 
+    public function getTokenEndpoint(): ?string
+    {
+        return $this->config['token_endpoint'] ?? null;
+    }
+
     public function getIntrospectionEndpoint(): ?string
     {
         return $this->config['introspection_endpoint'] ?? null;
diff --git a/src/Service/HealthCheck.php b/src/Service/HealthCheck.php
index 23093681aaa16334e3eb6240b6b547902f96032e..56f69b7dd06711c54f741796102fcc4a4b222e80 100644
--- a/src/Service/HealthCheck.php
+++ b/src/Service/HealthCheck.php
@@ -51,6 +51,21 @@ class HealthCheck implements CheckInterface
         $this->oidcProvider->getJWKs();
     }
 
+    public function checkRemoteValidation()
+    {
+        if (!$this->userProvider->usesRemoteValidation()) {
+            // Not configured, so don't test
+            return;
+        }
+
+        // Create a dummy token, and introspect it
+        $accessToken = $this->oidcProvider->createToken();
+        $token = $this->oidcProvider->introspectToken($accessToken);
+        if ($token['active'] !== true) {
+            throw new \RuntimeException('invalid token');
+        }
+    }
+
     public function checkTimeSync()
     {
         $providerTime = $this->oidcProvider->getProviderDateTime();
@@ -68,6 +83,7 @@ class HealthCheck implements CheckInterface
         $results[] = $this->checkMethod('Check if the OIDC config can be fetched', [$this, 'checkConfig']);
         $results[] = $this->checkMethod('Check if the OIDC public key can be fetched', [$this, 'checkPublicKey']);
         $results[] = $this->checkMethod('Check if the OIDC server time is in sync', [$this, 'checkTimeSync']);
+        $results[] = $this->checkMethod('Check if remote validation works (if enabled)', [$this, 'checkRemoteValidation']);
 
         return $results;
     }