Implicit Turnstile widget doesn’t respect valid token time

After 78 seconds the value attribute containing the token on hidden input field is removed. Docs say tokens are valid for 300 seconds. I see chlTimeoutMs: 78000 in the script section of the iframe?

Also, turnstile.getResponse() returns a token even after expiration time or if the hidden input value is empty. Is that correct behavior? Documentation says that function returns a widget’s state.


Bumping this topic for visibility. Is the token input field removal at 78 seconds intended behavior?

Hey there. I’m facing the same issue. After 78 seconds the response is cleared out from the hidden input. I thought the response was is valid for 5 minutes. Is it the intended behavior?

The token is no longer removed from the hidden input field. However, I’m now getting server-side validation error “timeout-or-duplicate” after about a minute and a half (78 seconds?). The token is valid prior to that time.

We recently have introduced a new callback to turnstile “timeout-callback” and refined the semantics for “expire-callback”. The semantics of the ‘new’ expire callback are as follows: It will only be called if a token had been previously issued and this token is about to expire (10 seconds before its actual expiry to account for potential network hickups), whereas before the expire callback was a little bit random. The timeout callback on the other hand will fire if a visitor has been prompted with an interactive challenge (i.e. the checkbox) but has failed to interact with it in a timely manner.

Should have mentioned I’m using the invisible widget type. All testing is performed on such. The “timeout-callback” doesn’t appear to fire with an invisible widget type (interactive challenge needed I guess). Page inactivity or not the token timeouts after about ~1m30s. The “expired-callback” fires predictably 10 seconds prior to the 300 second token expiration time.

Hi, thanks for providing an update on this issue.

To me it’s not quite clear what the difference is between timeout-callback and expired-callback. The documentation now says this:

expired-callback: A JavaScript callback that is invoked when the token expires and does not reset the widget.

timeout-callback: A JavaScript callback that is invoked when the challenge expires and resets the widget.

Does this mean that the widget will only be reset automatically when timeout-callback is provided?

How do I need to configure the widget if I want it to automatically trigger a new challenge when the initial challenge or token has expired?

1 Like

I’m having the same issue. After about 1:30-2 mins siteverify returns timeout-or-duplicate error. I’m using an invisible widget.

I’m experiencing the same issue. This is a large problem that the token needs to be verified on server side within 2 mins but the client side widget thinks it lasts 5 mins. I have created a work around, manually resetting the widget every 90 seconds and using both the timeout and expired callbacks.

    window.onLoadTurnstileCallback = () => {
      window.turnstile.render('#turnstile-container', {
        sitekey: sitekey,
        'timeout-callback': () => {
        'expired-callback': () => {

      // reset widget every 90 seconds
      intervalRef.current = setInterval(() => {
      }, 90000)

We’re experiencing the same issue. After about 1:30-2 mins siteverify returns timeout-or-duplicate error. The widget does expire after 5 minutes. Therefore, users who spend between 2 and 5 minutes filling in our forms are getting blocked.

Is this still an issue for users? I don’t think I’ve experienced this during my testing. I’ve let a form with the CAPTCHA widget sit and have watched the widget “reset” itself a few times.

I didn’t test extensively, but it appears this issue has been resolved. Invisible widget types now respect valid token time.

1 Like

Currently, I am unable to replicate the issue, and I believe it may have been resolved very recently. However, I did come across some form submissions that were blocked prior to February 17th, even though they appeared to be legitimate.