diff --git a/mod/bigbluebuttonbn/classes/external/meeting_info.php b/mod/bigbluebuttonbn/classes/external/meeting_info.php
index ffc18d0d96d..34d89b33f58 100644
--- a/mod/bigbluebuttonbn/classes/external/meeting_info.php
+++ b/mod/bigbluebuttonbn/classes/external/meeting_info.php
@@ -60,6 +60,8 @@ class meeting_info extends external_api {
      * @param int $groupid
      * @param bool $updatecache
      * @return array
+     * @throws \moodle_exception
+     * @throws restricted_context_exception
      */
     public static function execute(
         int $bigbluebuttonbnid,
@@ -91,7 +93,8 @@ class meeting_info extends external_api {
         // Check if the BBB server is working.
         $serverversion = bigbluebutton_proxy::get_server_version();
         if ($serverversion === null) {
-            throw new \moodle_exception('general_error_no_answer',
+            throw new \moodle_exception('general_error_no_answer', 'mod_bigbluebuttonbn',
+                bigbluebutton_proxy::get_server_not_available_url($instance),
                 bigbluebutton_proxy::get_server_not_available_message($instance));
         }
         return (array) meeting::get_meeting_info_for_instance($instance, $updatecache);
diff --git a/mod/bigbluebuttonbn/classes/local/exceptions/bigbluebutton_exception.php b/mod/bigbluebuttonbn/classes/local/exceptions/bigbluebutton_exception.php
index 29a05013e3e..e1f1a8fe7a2 100644
--- a/mod/bigbluebuttonbn/classes/local/exceptions/bigbluebutton_exception.php
+++ b/mod/bigbluebuttonbn/classes/local/exceptions/bigbluebutton_exception.php
@@ -19,7 +19,7 @@ namespace mod_bigbluebuttonbn\local\exceptions;
 use mod_bigbluebuttonbn\plugin;
 
 /**
- * Class bigbluebutton_exception generic exception
+ * Class bigbluebutton_exception generic exception. This is supposed to be recoverable.
  *
  * @package   mod_bigbluebuttonbn
  * @copyright 2010 onwards, Blindside Networks Inc
diff --git a/mod/bigbluebuttonbn/classes/local/exceptions/server_not_available_exception.php b/mod/bigbluebuttonbn/classes/local/exceptions/server_not_available_exception.php
index dcdb0fecb98..84afb519a6a 100644
--- a/mod/bigbluebuttonbn/classes/local/exceptions/server_not_available_exception.php
+++ b/mod/bigbluebuttonbn/classes/local/exceptions/server_not_available_exception.php
@@ -19,6 +19,9 @@ namespace mod_bigbluebuttonbn\local\exceptions;
 /**
  * Class server_not_available_exception
  *
+ * This kind of error cannot be recovered and should be displayed to the user
+ * signaling that there is an error in the configuration.
+ *
  * @package   mod_bigbluebuttonbn
  * @copyright 2010 onwards, Blindside Networks Inc
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
diff --git a/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php b/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php
index c2f1a512474..6f5201bf4ff 100644
--- a/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php
+++ b/mod/bigbluebuttonbn/classes/local/proxy/bigbluebutton_proxy.php
@@ -340,11 +340,16 @@ class bigbluebutton_proxy extends proxy_base {
      * @param instance $instance
      */
     public static function require_working_server(instance $instance): void {
+        $version = null;
         try {
-            self::get_server_version();
+            $version = self::get_server_version();
         } catch (server_not_available_exception $e) {
             self::handle_server_not_available($instance);
         }
+
+        if (empty($version)) {
+            self::handle_server_not_available($instance);
+        }
     }
 
     /**
@@ -384,7 +389,7 @@ class bigbluebutton_proxy extends proxy_base {
      */
     public static function get_server_not_available_url(instance $instance): string {
         if ($instance->is_admin()) {
-            return new moodle_url('/admin/settings.php', ['section' => 'modsettingbigbluebuttonbn']);
+            return new moodle_url('/admin/settings.php', ['section' => 'mod_bigbluebuttonbn_general']);
         } else if ($instance->is_moderator()) {
             return new moodle_url('/course/view.php', ['id' => $instance->get_course_id()]);
         } else {
diff --git a/mod/bigbluebuttonbn/classes/local/proxy/curl.php b/mod/bigbluebuttonbn/classes/local/proxy/curl.php
index db8e19b9f5b..11e4494c470 100644
--- a/mod/bigbluebuttonbn/classes/local/proxy/curl.php
+++ b/mod/bigbluebuttonbn/classes/local/proxy/curl.php
@@ -149,7 +149,9 @@ class curl extends \curl {
             return $xml;
         }
 
-        debugging('Issue retrieving information from the server: ' . $response, DEBUG_DEVELOPER);
+        $debugabstract = html_to_text($response);
+        $debugabstract = substr($debugabstract, 0, 1024); // Limit to small amount of info so we do not overload logs.
+        debugging('Issue retrieving information from the server: ' . $debugabstract, DEBUG_DEVELOPER);
         return null;
     }
 }
diff --git a/mod/bigbluebuttonbn/classes/local/proxy/proxy_base.php b/mod/bigbluebuttonbn/classes/local/proxy/proxy_base.php
index 1c941018e84..a734b45e81a 100644
--- a/mod/bigbluebuttonbn/classes/local/proxy/proxy_base.php
+++ b/mod/bigbluebuttonbn/classes/local/proxy/proxy_base.php
@@ -40,7 +40,7 @@ abstract class proxy_base {
      * Sometimes the server sends back some error and errorKeys that
      * can be converted to Moodle error messages
      */
-    const MEETING_ERROR = [
+    const BBB_TO_MOODLE_ERROR_CODE = [
         'checksumError' => 'index_error_checksum',
         'notFound' => 'general_error_not_found',
         'maxConcurrent' => 'view_error_max_concurrent',
@@ -101,31 +101,61 @@ abstract class proxy_base {
      * @throws server_not_available_exception
      */
     protected static function assert_returned_xml($xml, ?array $additionaldetails = null): void {
-        if (empty($xml)) {
+        $messagekey = '';
+        if (!empty($xml)) {
+            $messagekey = (string) ($xml->messageKey ?? '');
+        }
+        if (empty($xml) || static::is_known_server_unavailable_errorcode($messagekey)) {
+            $errorcode = self::get_errorcode_from_xml_messagekey($messagekey);
             throw new server_not_available_exception(
-                'general_error_no_answer',
+                $errorcode,
                 plugin::COMPONENT,
-                (new moodle_url('/admin/settings.php?section=modsettingbigbluebuttonbn'))->out()
+                (new moodle_url('/admin/settings.php?section=modsettingbigbluebuttonbn'))->out(),
             );
         }
+        // If it is a checksum error, this is equivalent to the server not being available.
+        // So we treat it the same way as if there is not answer.
         if (is_bool($xml) && $xml) {
             // Nothing to do here, this might be a post returning that everything went well.
             return;
         }
         if ((string) $xml->returncode == 'FAILED') {
-            $messagekey = (string) $xml->messageKey ?? '';
+            $errorcode = self::get_errorcode_from_xml_messagekey($messagekey);
             if (!$additionaldetails) {
                 $additionaldetails = [];
             }
             $additionaldetails['xmlmessage'] = (string) $xml->message ?? '';
-            if (empty($messagekey) || empty(self::MEETING_ERROR[$messagekey])) {
-                $messagekey = 'general_error_unable_connect';
-            }
 
-            throw new bigbluebutton_exception($messagekey, json_encode($additionaldetails));
+            throw new bigbluebutton_exception($errorcode, json_encode($additionaldetails));
         }
     }
 
+    /**
+     * Get Moodle error code from returned Message Key
+     *
+     * @param string $messagekey
+     * @return string
+     */
+    private static function get_errorcode_from_xml_messagekey(string $messagekey): string {
+        $errorcode = 'general_error_no_answer';
+        if ($messagekey) {
+            $errorcode = self::BBB_TO_MOODLE_ERROR_CODE[$messagekey] ?? $errorcode;
+        }
+        return $errorcode;
+    }
+
+    /**
+     * Get Moodle error code from returned Message Key
+     *
+     * @param string $messagekey
+     * @return string
+     */
+    private static function is_known_server_unavailable_errorcode(string $messagekey): string {
+        // For now, only checksumError is supposed to mean that the server is unavailable.
+        // Other errors are recoverable.
+        return in_array($messagekey, ['checksumError']);
+    }
+
     /**
      * Fetch the XML from an endpoint and test for success.
      *
diff --git a/mod/bigbluebuttonbn/lib.php b/mod/bigbluebuttonbn/lib.php
index 00c25cd3d26..db8b31c5f73 100644
--- a/mod/bigbluebuttonbn/lib.php
+++ b/mod/bigbluebuttonbn/lib.php
@@ -30,9 +30,11 @@ use core_calendar\local\event\entities\action_interface;
 use mod_bigbluebuttonbn\completion\custom_completion;
 use mod_bigbluebuttonbn\instance;
 use mod_bigbluebuttonbn\local\bigbluebutton;
+use mod_bigbluebuttonbn\local\exceptions\server_not_available_exception;
 use mod_bigbluebuttonbn\local\helpers\files;
 use mod_bigbluebuttonbn\local\helpers\mod_helper;
 use mod_bigbluebuttonbn\local\helpers\reset;
+use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
 use mod_bigbluebuttonbn\logger;
 use mod_bigbluebuttonbn\meeting;
 use mod_bigbluebuttonbn\recording;
@@ -482,8 +484,20 @@ function mod_bigbluebuttonbn_core_calendar_provide_event_action(
     $instance = instance::get_from_instanceid($bigbluebuttonbn->id);
     // Get if the room is available.
     $roomavailable = $instance->is_currently_open();
-    // Get if the user can join.
-    $meetinginfo = meeting::get_meeting_info_for_instance($instance);
+
+    $meetinginfo = null;
+    // Check first if the server can be contacted.
+    try {
+        if (empty(bigbluebutton_proxy::get_server_version())) {
+            // In this case we should already have debugging message printed.
+            return null;
+        }
+        // Get if the user can join.
+        $meetinginfo = meeting::get_meeting_info_for_instance($instance);
+    } catch (moodle_exception $e) {
+        debugging('Error - Cannot retrieve info from meeting ('.$instance->get_meeting_id().') ' . $e->getMessage());
+        return null;
+    }
     $usercanjoin = $meetinginfo->canjoin;
 
     // Check if the room is closed and the user has already joined this session or played the record.
diff --git a/mod/bigbluebuttonbn/view.php b/mod/bigbluebuttonbn/view.php
index b345024a528..faa5bc8de43 100644
--- a/mod/bigbluebuttonbn/view.php
+++ b/mod/bigbluebuttonbn/view.php
@@ -26,6 +26,7 @@
  */
 
 use mod_bigbluebuttonbn\instance;
+use mod_bigbluebuttonbn\local\exceptions\server_not_available_exception;
 use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
 use mod_bigbluebuttonbn\logger;
 use mod_bigbluebuttonbn\output\view_page;
@@ -78,6 +79,12 @@ $PAGE->set_heading($course->fullname);
 // Output starts.
 $renderer = $PAGE->get_renderer('mod_bigbluebuttonbn');
 
+try {
+    $renderedinfo = $renderer->render(new view_page($instance));
+} catch (server_not_available_exception $e) {
+    bigbluebutton_proxy::handle_server_not_available($instance);
+}
+
 echo $OUTPUT->header();
 
 // Validate if the user is in a role allowed to join.
@@ -92,7 +99,7 @@ if (!$instance->can_join() && $instance->get_type() != instance::TYPE_RECORDING_
     }
 }
 
-echo $renderer->render(new view_page($instance));
+echo $renderedinfo;
 
 // Output finishes.
 echo $OUTPUT->footer();