Web Push Error 410: the push subscription has expired or the user has unsubscribed

Subscribing users to web push notifications on your website is not enough: you also need to manage and renew their push subscriptions properly over time, otherwise you will lose subscribers.

Note: If you use Pushpad all the management and renewal of the push subscriptions is performed automatically by our service and you don’t have to worry about it. Read below if you are interested in the technical details or if you are building your own solution from scratch.

When a user visits your website and subscribes to your notifications, you get a secret endpoint (URL), which allows you to deliver notifications to that specific device.

However the endpoint may expire or change after some time (as we have already described) and you will get an error like this when you try to send a notification to it:

410 push subscription has unsubscribed or expired

This can happen mainly for two reasons:

  • the user has unsubscribed from your notifications by changing the browser preferences
  • the push subscription has been replaced / renewed automatically by the browser and you must update it in your application server.

In the first case, when the user has unsubscribed, you can’t do much… When you try to send a notification and you get 410 Gone, you should simply remove that subscription from your server.

For the second case, the user is still subscribed and wants to receive your notifications… he has simply changed address (i.e. he has a new push subscription endpoint). This means that you must listen for changes of the endpoint and update it on your application server when it changes.

In order to detect changes of the endpoint and update it on your server before it returns the 410 error code you can use the pushsubscriptionchange event in your service worker.

This is the code that we use for Pushpad for example:

self.addEventListener('pushsubscriptionchange', function(event) {
  event.waitUntil(
    fetch('https://pushpad.xyz/pushsubscriptionchange', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        old_endpoint: event.oldSubscription ? event.oldSubscription.endpoint : null,
        new_endpoint: event.newSubscription ? event.newSubscription.endpoint : null,
        new_p256dh: event.newSubscription ? event.newSubscription.toJSON().keys.p256dh : null,
        new_auth: event.newSubscription ? event.newSubscription.toJSON().keys.auth : null
      })
    })
  );
});

Then on the server you need to find the old endpoint and replace it with the new one (you also need to update the p256dh and auth). In this way you can also retain all the customer data associated to the push subscription.

If you want more details you can read the Subscription Refreshes section in the standard. You can also find a description of web push errors, including 410 Gone, on the Mozilla autopush documentation.

Leave a Comment