Pinhandling for OTP_RANDOM_PIN

Dear everyone,

I am trying to configure a policy, which requires and set an random PIN to the OTP. This PIN should be send via email to the user. But for me it is not clear, what I have to put into the value field “pinhandling”.

I tried a lot of things, for example

  • send
  • base
  • privacyidea.lib.pinhandling.base
  • privacyidea.lib.pinhandling.send

But anytime I try to create a new TOTP Token I receive an HTTP 500 error. Does anyone have a hint for me? I am not able to log the pin to the logfile or to send it via email.

Thanks and all the best for you


Here is the part of the logfile:

2020-12-22 13:00:28,086][19291][140078366598912][INFO][privacyidea.lib.user:233] user ‘testuser’ found in resolver ‘domain’
[2020-12-22 13:00:28,087][19291][140078366598912][INFO][privacyidea.lib.user:234] userid resolved to ‘54a20861-e55d-41d7-a806-181a5b0c1528’
[2020-12-22 13:00:28,096][19291][140078366598912][ERROR][] Exception on /token/init [POST]
Traceback (most recent call last):
File “/opt/privacyidea/lib/python3.7/site-packages/flask/”, line 2447, in wsgi_app
response = self.full_dispatch_request()
File “/opt/privacyidea/lib/python3.7/site-packages/flask/”, line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File “/opt/privacyidea/lib/python3.7/site-packages/flask/”, line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File “/opt/privacyidea/lib/python3.7/site-packages/flask/”, line 39, in reraise
raise value
File “/opt/privacyidea/lib/python3.7/site-packages/flask/”, line 1950, in full_dispatch_request
rv = self.dispatch_request()
File “/opt/privacyidea/lib/python3.7/site-packages/flask/”, line 1936, in dispatch_request
return self.view_functionsrule.endpoint
File “/opt/privacyidea/lib/python3.7/site-packages/privacyidea/api/lib/”, line 154, in policy_wrapper
return wrapped_function(*args, **kwds)
File “/opt/privacyidea/lib/python3.7/site-packages/privacyidea/api/lib/”, line 154, in policy_wrapper
return wrapped_function(*args, **kwds)
File “/opt/privacyidea/lib/python3.7/site-packages/privacyidea/api/lib/”, line 154, in policy_wrapper
return wrapped_function(*args, **kwds)
[Previous line repeated 4 more times]
File “/opt/privacyidea/lib/python3.7/site-packages/privacyidea/api/lib/”, line 153, in policy_wrapper
File “/opt/privacyidea/lib/python3.7/site-packages/privacyidea/api/lib/”, line 267, in init_random_pin
pin_handler = pin_handler_class()
TypeError: ‘module’ object is not callable
[2020-12-22 13:00:28,103][19291][140078366598912][ERROR][privacyidea.lib.auditmodules.sqlaudit:261] exception DataError(’(pymysql.err.DataError) (1406, “Data too long for column ‘info’ at row 1”)’)
[2020-12-22 13:00:28,103][19291][140078366598912][ERROR][privacyidea.lib.auditmodules.sqlaudit:262] DATA: {‘success’: False, ‘serial’: None, ‘user’: ‘testuser’, ‘realm’: ‘domain’, ‘resolver’: ‘domain’, ‘token_type’: None, ‘client’: ‘’, ‘client_user_agent’: ‘chrome’, ‘privacyidea_server’: ‘otp.domain’, ‘action’: ‘POST /token/init’, ‘action_detail’: ‘’, ‘info’: ‘500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.’, ‘policies’: ‘require_pin_for_otp,require_pin_for_otp’}

and thank you for using privacyIDEA.

As the error log says, the module is not callable.
And as the documentation says you must provide the Handler Class.

I.e. the classname “PinHanlder” in the module file lib/pinhandling/
You can write your own Handler Class (inherited from PinHanlder) in your own Module file like lib/myfiles/, then you would have to enter like lib.myfiles.coolhandler.PinHandler - or however you call it.

To be complete, you could also use three eventhandlers like

  • post token handler to set pin
  • post notification handler to send the pin
  • post PostMangler handler to remove the pin from the response.