diff --git a/tools/setup-ssh b/tools/setup-ssh
index 565a67dbf3c01628876b4d61f9b220b0f7df073a..d54fa10a524846ec1a982e3b22733797bf279512 100755
--- a/tools/setup-ssh
+++ b/tools/setup-ssh
@@ -38,6 +38,7 @@ from ganeti import cli
 from ganeti import constants
 from ganeti import errors
 from ganeti import netutils
+from ganeti import ssconf
 from ganeti import ssh
 from ganeti import utils
 
@@ -48,6 +49,54 @@ class RemoteCommandError(errors.GenericError):
   """
 
 
+class JoinCheckError(errors.GenericError):
+  """Exception raised if join check fails.
+
+  """
+
+
+def _CheckJoin(transport):
+  """Checks if a join is safe or dangerous.
+
+  Note: This function relies on the fact, that all
+  hosts have the same configuration at compile time of
+  Ganeti. So that the constants do not mismatch.
+
+  @param transport: The paramiko transport instance
+  @return: True if the join is safe; False otherwise
+
+  """
+  sftp = transport.open_sftp_client()
+  ss = ssconf.SimpleStore()
+  ss_cluster_name_path = ss.KeyToFilename(constants.SS_CLUSTER_NAME)
+
+  cluster_files = {
+    ss_cluster_name_path: utils.ReadFile(ss_cluster_name_path),
+    constants.NODED_CERT_FILE: utils.ReadFile(constants.NODED_CERT_FILE),
+    }
+
+  try:
+    remote_noded_file = _ReadSftpFile(sftp, constants.NODED_CERT_FILE)
+  except IOError:
+    # We can just assume that the file doesn't exist as such error reporting
+    # is lacking from paramiko
+    #
+    # We don't have the noded certificate. As without the cert, the
+    # noded is not running, we are on the safe bet to say that this
+    # node doesn't belong to a cluster
+    return True
+
+  try:
+    remote_cluster_name = _ReadSftpFile(sftp, ss_cluster_name_path)
+  except IOError:
+    # This can indicate that a previous join was not successful
+    # So if the noded cert was found and matches we are fine
+    return cluster_files[constants.NODED_CERT_FILE] == remote_noded_file
+
+  return (cluster_files[constants.NODED_CERT_FILE] == remote_noded_file and
+          cluster_files[ss_cluster_name_path] == remote_cluster_name)
+
+
 def _RunRemoteCommand(transport, command):
   """Invokes and wait for the command over SSH.
 
@@ -84,6 +133,21 @@ def _InvokeDaemonUtil(transport, command):
   _RunRemoteCommand(transport, "%s %s" % (constants.DAEMON_UTIL, command))
 
 
+def _ReadSftpFile(sftp, filename):
+  """Reads a file over sftp.
+
+  @param sftp: An open paramiko SFTP client
+  @param filename: The filename of the file to read
+  @return: The content of the file
+
+  """
+  remote_file = sftp.open(filename, "r")
+  try:
+    return remote_file.read()
+  finally:
+    remote_file.close()
+
+
 def _WriteSftpFile(sftp, name, perm, data):
   """SFTPs data to a remote file.
 
@@ -159,8 +223,8 @@ def ParseOptions():
   """
   program = os.path.basename(sys.argv[0])
 
-  parser = optparse.OptionParser(usage=("%prog [--debug|--verbose] <node>"
-                                        " <node...>"), prog=program)
+  parser = optparse.OptionParser(usage=("%prog [--debug|--verbose] [--force]"
+                                        " <node> <node...>"), prog=program)
   parser.add_option(cli.DEBUG_OPT)
   parser.add_option(cli.VERBOSE_OPT)
   parser.add_option(cli.NOSSH_KEYCHECK_OPT)
@@ -172,6 +236,9 @@ def ParseOptions():
   parser.add_option(optparse.Option("--key-type", dest="key_type",
                                     choices=("rsa", "dsa"), default="dsa",
                                     help="The private key type (rsa or dsa)"))
+  parser.add_option(optparse.Option("-j", "--force-join", dest="force_join",
+                                    action="store_true", default=False,
+                                    help="Force the join of the host"))
 
   (options, args) = parser.parse_args()
 
@@ -368,6 +435,12 @@ def main():
       continue
     try:
       try:
+        if not _CheckJoin(transport):
+          if options.force_join:
+            logging.warning("Host %s failed join check, forced to continue",
+                            host)
+          else:
+            raise JoinCheckError("Host %s failed join check" % host)
         SetupSSH(transport)
       except errors.GenericError, err:
         logging.error("While doing setup on host %s an error occured: %s",