This indicates that a signed token request, sent to Ably to request a token, has been used before.  The nonce checks within the Ably service ensure that a signed token request can only be used once, and as such, the rejection of a token request that has been previously used is a valid part of the security measures in the platform design.


This error can be caused by network connectivity issues on the client side. What can happen is that the HTTP request to turn a signed token request into a token gets through to Ably, but the client never gets the response due to network issues. Then, when the client automatically retries the http request in a fallback data center it will get this error.


If you are getting this problem consistently (rather than just occasionally given network issues), here are some things you should check which may be causing it:


  • Your auth server should not cache the signed token requests you send to clients. ¬†Each token request must be unique.
  • If you are using authCallback, make sure you obtain a new token request each time the authCallback is called -- do not cache it. If you are obtaining a token request with an HTTP request from inside an authCallback, make sure that the request will not be cached by any intermediate layer, e.g. by setting the Cache-Control header to 'no-cache, no-store, must-revalidate', or by setting a cache-busting querystring param (such as ?rnd=73849275, where the random number is regenerated for every request)


If you've gone through the list above and are still getting this error, try to get a debug-level log of the generation of a token request, and contact us for more help.


Top tip


# 1 If you are using an authCallback, double check that it is not possible that the same token request is being returned on every invocation. We have often seen customers instance a library as follows, which leads to this issue:


var tokenRequest = "<new token request>";
var ably = Ably.Realtime.new({
  authCallback: function(tokenParams, function(err, tokenOrTokenRequest) {
    /* This is a mistake.  The tokenRequest is not renewed.  
       A new token request should be requested from your server at this point */
    callback(null, tokenRequest);
  }
});