diff --git a/uffd-ldapd b/uffd-ldapd
index 587c449e73021c409b7b66a3dacf60fd65ccc5ab..0b64cf4ef3b41ae3f9402f34fb25c4af193f4c2a 100755
--- a/uffd-ldapd
+++ b/uffd-ldapd
@@ -11,7 +11,7 @@ from cachecontrol import CacheControl
 from cachecontrol.heuristics import ExpiresAfter
 
 import ldapserver
-from ldapserver.exceptions import LDAPInvalidCredentials
+from ldapserver.exceptions import LDAPInvalidCredentials, LDAPInsufficientAccessRights, LDAPUnwillingToPerform
 from ldapserver.schema import RFC2307BIS_SCHEMA, RFC2798_SCHEMA
 
 logger = logging.getLogger(__name__)
@@ -96,8 +96,15 @@ class UffdLDAPRequestHandler(ldapserver.LDAPRequestHandler):
 			return True
 		if not dn.is_direct_child_of(self.subschema.DN('ou=users') + self.dn_base) or len(dn[0]) != 1 or dn[0][0].attribute != 'uid':
 			raise LDAPInvalidCredentials()
-		if self.api.check_password(loginname=dn[0][0].value, password=password):
-			return True
+		try:
+			if self.api.check_password(loginname=dn[0][0].value, password=password):
+				return True
+		except requests.exceptions.HTTPError as exc:
+			if exc.response.status_code == 403: # We don't have "checkpassword" scope
+				raise LDAPInsufficientAccessRights() from exc
+			if exc.response.status_code == 429: # Ratelimited
+				raise LDAPUnwillingToPerform('Too Many Requests') from exc
+			raise exc
 		raise LDAPInvalidCredentials()
 
 	supports_sasl_plain = True
@@ -105,10 +112,16 @@ class UffdLDAPRequestHandler(ldapserver.LDAPRequestHandler):
 	def do_bind_sasl_plain(self, identity, password, authzid=None):
 		if authzid is not None and identity != authzid:
 			raise LDAPInvalidCredentials()
-		user = self.api.check_password(loginname=identity, password=password)
-		if user is None:
-			raise LDAPInvalidCredentials()
-		return user
+		try:
+			if self.api.check_password(loginname=identity, password=password):
+				return True
+		except requests.exceptions.HTTPError as exc:
+			if exc.response.status_code == 403: # We don't have "checkpassword" scope
+				raise LDAPInsufficientAccessRights() from exc
+			if exc.response.status_code == 429: # Ratelimited
+				raise LDAPUnwillingToPerform('Too Many Requests') from exc
+			raise exc
+		raise LDAPInvalidCredentials()
 
 	def do_search(self, baseobj, scope, filterobj):
 		yield from super().do_search(baseobj, scope, filterobj)