diff --git a/certificates.py b/certificates.py
index 8b23e40bdefa416e574e71744c90196c31bb2280..d4b042f07c106daa6528e6e86f0860ee5f608d79 100644
--- a/certificates.py
+++ b/certificates.py
@@ -239,6 +239,10 @@ def send_token(user: 'UserAccount') -> Tuple[bool, Optional[str]]:
     # Print URL to console (for debugging or when email sending doesn't work)
     print(f"Certificate access URL for '{user.username}': {access_url}")
 
+    if not config['smtp']:
+        # SMTP not configured, show URL to the admin (as part of error message) instead
+        return False, f"Can't send email to the user. URL to download the certificate: {access_url}"
+
     # Send the token via email
     name = f"{user.firstname} {user.lastname}".strip() or user.username
     try:
diff --git a/main.py b/main.py
index 9a5f2644c64793767f179e8b35c1fd8c9f309659..1cac4824b9d24ed8f8b1b30824cd1080c11b581e 100644
--- a/main.py
+++ b/main.py
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import os.path
 import sys
 from datetime import datetime, timezone
 from typing import List, Dict, Optional, Union, Tuple
@@ -17,44 +18,54 @@ from config import config # module serving as a global namespace for configurati
 
 # Load and check configuration - paths, URLs, api keys, etc.
 invalid_configuration_error = None
+invalid_smtp = None
 try:
     config.update(yaml.safe_load(open("config.yml", "r")))
     errors = []
+    smtp_errors = []
 
     # Check presence of all mandatory configuration parameters
     for attr in ('soctoolsproxy', 'ca_cert_file', 'easyrsa_bin', 'easyrsa_ca_dir', 'token_file',
                  'mgmt_user_name', 'mgmt_user_cert_path', 'mgmt_user_key_path', 'user_mgmt_base_url',
                  'keycloak_base_url', 'keycloak_users_url', 'keycloak_admin_password',
                  'misp_api_key', 'thehive_api_key', 'thehive_org_name', 'cortex_api_key', 'cortex_org_name',):
-        if not config[attr]:
+        if attr not in config or not config[attr]:
             errors.append(f'Missing mandatory parameter "{attr}".')
+            config[attr] = None # to avoid attr-access errors in some imported modules
 
     # Check soctoolsproxy
-    if not re.match('[a-zA-Z0-9.:-]+', config['soctoolsproxy']):
+    if not re.fullmatch('[a-zA-Z0-9.:-]+', config['soctoolsproxy'] or 'a'):
         errors.append("'soctoolsproxy' is not a valid hostname or IP address.")
 
     # Check smtp params, set defaults
     if not isinstance(config.get('smtp'), dict):
-        errors.append('Missing mandatory parameter "smtp" or it is not dict.')
-    if not re.match('[a-zA-Z0-9.:-]+', config['smtp'].get('host')):
-        errors.append('Missing mandatory parameter "smtp.host" or is not a valid hostname or IP address.')
-    if not config['smtp'].get('sender'):
-        errors.append('Missing mandatory parameter "smtp.sender".')
-    if not config['smtp'].get('port'):
-        config['smtp']['port'] = 465
+        smtp_errors.append('Parameter "smtp" is missing or it is not a dict.')
+    else:
+        if not re.match('[a-zA-Z0-9.:-]+', config['smtp'].get('host')):
+            smtp_errors.append('Parameter "smtp.host" is missing or it is not a valid hostname or IP address.')
+        if not config['smtp'].get('sender'):
+            smtp_errors.append('Parameter "smtp.sender" is missing.')
+        if not config['smtp'].get('port'):
+            config['smtp']['port'] = 465
 
     if errors:
-        invalid_configuration_error = "Configuration error(s):\n" + "\n".join(errors)
+        invalid_configuration_error = "Configuration error(s):\n" + "\n".join(errors + smtp_errors)
+    if smtp_errors:
+        invalid_smtp = f"WARNING: SMTP not properly configured, it is not possible to send emails ({' '.join(smtp_errors)})"
+        config['smtp'] = None
 except Exception as e:
     invalid_configuration_error = f"Can't load configuration: {e}"
 
 
-print(f"Config loaded:\nsoctoolsproxy={config['soctoolsproxy']}\nkeycloak_base_url={config['keycloak_base_url']}\n"
-      f"keycloak_admin_password={config['keycloak_admin_password'][:3]}...{config['keycloak_admin_password'][-4:]}\n"
-      f"misp_api_key={config['misp_api_key'][:3]}...{config['misp_api_key'][-4:]}\n"
-      f"thehive_api_key={config['thehive_api_key'][:3]}...{config['thehive_api_key'][-4:]}\n"
-      f"cortex_api_key={config['cortex_api_key'][:3]}...{config['cortex_api_key'][-4:]}\n"
-      f"thehive_org_name={config['thehive_org_name']}\n")
+if invalid_configuration_error:
+    print("ERROR: " + invalid_configuration_error)
+else:
+    print(f"Config loaded:\nsoctoolsproxy={config['soctoolsproxy']}\nkeycloak_base_url={config['keycloak_base_url']}\n"
+          f"keycloak_admin_password={config['keycloak_admin_password'][:3]}...{config['keycloak_admin_password'][-4:]}\n"
+          f"misp_api_key={config['misp_api_key'][:3]}...{config['misp_api_key'][-4:]}\n"
+          f"thehive_api_key={config['thehive_api_key'][:3]}...{config['thehive_api_key'][-4:]}\n"
+          f"cortex_api_key={config['cortex_api_key'][:3]}...{config['cortex_api_key'][-4:]}\n"
+          f"thehive_org_name={config['thehive_org_name']}\n")
 
 
 import certificates
@@ -69,10 +80,12 @@ app.secret_key = "ASDF1234 - CHANGE ME!" # TODO: set dynamically to something ra
 # If there is config error, report it instead of trying to render a page
 @app.before_request
 def config_check():
+    # in case of fatal config error, return error 500 with an error message
     if invalid_configuration_error is not None:
         return make_response(f"500 Internal Server Error\n{'='*25}\n\n{invalid_configuration_error}\n\n"
-                             "Fix the configuration file and restart the user-mgmt-ui service "
-                             "('systemctl restart user-mgmt-ui')", 500, {'Content-Type': 'text/plain'})
+                             f"Fix the configuration file ('{os.path.abspath('config.yml')}') and restart"
+                             " the user-mgmt-ui service ('systemctl restart user-mgmt-ui')",
+                             500, {'Content-Type': 'text/plain'})
 
 
 def redirect_to_main_page():
@@ -289,6 +302,11 @@ class AddUserForm(FlaskForm):
 
 @app.route("/")
 def main():
+    # In case of invalid SMTP configuration, show warning message
+    if invalid_smtp is not None and request.endpoint != "export_certificate":
+        flash(invalid_smtp + f" To fix it, edit the configuration file ('{os.path.abspath('config.yml')}') and restart"
+                             " the user-mgmt-ui service ('systemctl restart user-mgmt-ui').", "warning")
+
     # Load existing users from Keycloak
     try:
         users = kc_get_users()
@@ -642,15 +660,13 @@ def send_token(username: str):
 
 
 # TODO:
-#  - revoke and delete certificate when user is deleted
-#  - send tokens via email
 #  - authentication/authorization to this GUI
 
-@app.route("/test_cert/<func>")
-def test_cert_endpoint(func):
-    # run any function from "certificates" module
-    result = str(getattr(certificates, func)(**request.args))
-    return make_response(result)
+# @app.route("/test_cert/<func>")
+# def test_cert_endpoint(func):
+#     # run any function from "certificates" module
+#     result = str(getattr(certificates, func)(**request.args))
+#     return make_response(result)
 
 # When the script is run directly, run the application on a local development server.
 # Optionally pass two parameters, 'host' (IP to listen on) and 'port',