diff --git a/README-host.md b/README-host.md
index 5f540cac10255ec7af0cce6c2b46496bb7a06b70..4ee4cbe45abf3ee8c1af0c98bc0a2a7f76fdad65 100644
--- a/README-host.md
+++ b/README-host.md
@@ -173,14 +173,14 @@ Example playbook to ensure host presence with a random password:
       name: host01.example.com
       random: yes
       force: yes
+      update_password: on_create
     register: ipahost
 
   - name: Print generated random password
     debug:
       var: ipahost.host.randompassword
 ```
-Please remember that the `force` tag will also force the generation of a new random password even if the host already exists and if `update_password` is limited to `on_create`.
-
+Please remember that a new random password will be generated for an existing but not enrolled host if `update_password` is not limited to `on_create`. For an already enrolled host the task will fail with `update_password` default setting `always`.
 
 Example playbook to ensure presence of several hosts with a random password:
 
@@ -198,9 +198,11 @@ Example playbook to ensure presence of several hosts with a random password:
       - name: host01.example.com
         random: yes
         force: yes
+        update_password: on_create
       - name: host02.example.com
         random: yes
         force: yes
+        update_password: on_create
     register: ipahost
 
   - name: Print generated random password for host01.example.com
@@ -211,7 +213,7 @@ Example playbook to ensure presence of several hosts with a random password:
     debug:
       var: ipahost.host["host02.example.com"].randompassword
 ```
-Please remember that the `force` tag will also force the generation of a new random password even if the host alreay exists and if `update_password` is limited to `on_create`.
+Please remember that a new random password will be generated for an existing but not enrolled host if `update_password` is not limited to `on_create`. For an already enrolled host the task will fail with `update_password` default setting `always`.
 
 
 Example playbook to ensure presence of host member principal:
@@ -337,8 +339,8 @@ Variable | Description | Required
 `location` \| `ns_host_location` | Host location (e.g. "Lab 2"). | no
 `platform` \| `ns_hardware_platform` | Host hardware platform (e.g. "Lenovo T61"). | no
 `os` \| `ns_os_version` | Host operating system and version (e.g. "Fedora 9"). | no
-`password` \| `user_password` \| `userpassword` | Password used in bulk enrollment. | no
-`random` \| `random_password` |  Initiate the generation of a random password to be used in bulk enrollment. | no
+`password` \| `user_password` \| `userpassword` | Password used in bulk enrollment for absent or not enrolled hosts. | no
+`random` \| `random_password` |  Initiate the generation of a random password to be used in bulk enrollment for absent or not enrolled hosts. | no
 `certificate` \| `usercertificate` | List of base-64 encoded host certificates | no
 `managedby` \| `principalname` \| `krbprincipalname` | List of hosts that can manage this host | no
 `principal` \| `principalname` \| `krbprincipalname` | List of principal aliases for this host | no
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
index 42bd7e1faf6fbb1f6f246ae72a4c623839e88ee9..4778386cfd237f235897287b9bfe8bb46073ce6c 100644
--- a/plugins/modules/ipahost.py
+++ b/plugins/modules/ipahost.py
@@ -420,23 +420,22 @@ if six.PY3:
 def find_host(module, name):
     _args = {
         "all": True,
-        "fqdn": to_text(name),
     }
 
-    _result = api_command(module, "host_find", to_text(name), _args)
+    try:
+        _result = api_command(module, "host_show", to_text(name), _args)
+    except ipalib_errors.NotFound as e:
+        msg = str(e)
+        if "host not found" in msg:
+            return None
+        module.fail_json(msg="host_show failed: %s" % msg)
 
-    if len(_result["result"]) > 1:
-        module.fail_json(
-            msg="There is more than one host '%s'" % (name))
-    elif len(_result["result"]) == 1:
-        _res = _result["result"][0]
-        certs = _res.get("usercertificate")
-        if certs is not None:
-            _res["usercertificate"] = [encode_certificate(cert) for
-                                       cert in certs]
-        return _res
-    else:
-        return None
+    _res = _result["result"]
+    certs = _res.get("usercertificate")
+    if certs is not None:
+        _res["usercertificate"] = [encode_certificate(cert) for
+                                   cert in certs]
+    return _res
 
 
 def find_dnsrecord(module, name):
@@ -903,9 +902,25 @@ def main():
                     # Found the host
                     if res_find is not None:
                         # Ignore password with update_password == on_create
-                        if update_password == "on_create" and \
-                           "userpassword" in args:
-                            del args["userpassword"]
+                        if update_password == "on_create":
+                            # Ignore userpassword and random for existing
+                            # host if update_password is "on_create"
+                            if "userpassword" in args:
+                                del args["userpassword"]
+                            if "random" in args:
+                                del args["random"]
+                        elif "userpassword" in args or "random" in args:
+                            # Allow an existing OTP to be reset but don't
+                            # allow a OTP or to be added to an enrolled host.
+                            # Also do not allow to change the password for an
+                            # enrolled host.
+
+                            if not res_find["has_password"] and \
+                               res_find["has_keytab"]:
+                                ansible_module.fail_json(
+                                    msg="%s: Password cannot be set on "
+                                    "enrolled host." % host
+                                )
 
                         # Ignore force, ip_address and no_reverse for mod
                         for x in ["force", "ip_address", "no_reverse"]:
@@ -953,7 +968,7 @@ def main():
                         principal_add, principal_del = gen_add_del_lists(
                             principal, res_find.get("principal"))
                         # Principals are not returned as utf8 for IPA using
-                        # python2 using host_find, therefore we need to
+                        # python2 using host_show, therefore we need to
                         # convert the principals that we should remove.
                         principal_del = [to_text(x) for x in principal_del]
 
diff --git a/tests/host/test_host_random.yml b/tests/host/test_host_random.yml
index 4d1b2545e6ae94d71e0adf5a5643b2fdac7e4757..376740c736ae421bd0b8e72dd27768824f4f2983 100644
--- a/tests/host/test_host_random.yml
+++ b/tests/host/test_host_random.yml
@@ -77,6 +77,22 @@
     debug:
       var: ipahost.host["{{host2_fqdn }}"].randompassword
 
+  - name: Enrolled host "{{ groups.ipaserver[0] }}" fails to set random password with update_password always
+    ipahost:
+      ipaadmin_password: SomeADMINpassword
+      hosts:
+      - name: "{{ groups.ipaserver[0] }}"
+        random: yes
+      update_password: always
+    register: ipahost
+    failed_when: ipahost.changed
+
+  - assert:
+      that:
+      - ipahost.host["{{ groups.ipaserver[0] }}"].randompassword is
+        not defined
+      - "'Password cannot be set on enrolled host' in ipahost.msg"
+
   - name: Hosts "{{ host1_fqdn }}" and "{{ host2_fqdn }}" absent
     ipahost:
       ipaadmin_password: SomeADMINpassword