So upgrading to Devise 3.1.0 left some ‘cruft’ in a view that I hadn’t touched in a while.
According to this blog post, you need to change your Devise mailer to use @token instead of the old @resource.confirmation_token.
Find this in app/views/<user>/mailer/confirmation_instructions.html.erb and change it to something like:
<p>Welcome <%= @resource.email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) %></p>
This should fix any token-based confirmation problems you’re having. This is likely to fix any unlock or reset password token problems as well.