Mail scanners keep clicking your users' password-reset links before they do. Install the module, read the log and keep the bots away from the link.
Your user requests a new password. Drupal emails a single-use link.
A mail-security gateway, link-preview service or crawler fetches the URL in transit.
Your user opens the email and clicks the link, seconds later.
Shy One-Time intercepts requests to user.reset and user.reset.login, so bots never spend the token. Crawlers get a 403 and the user agents you list get a 302 to the login page.
Mail scanners, preview bots and crawlers open one-time links before your users, so Drupal says the link “has either been used or is no longer valid”.
composer require drupal/shy_one_time → drush en shy_one_time -y. Known crawlers are blocked out of the box (CrawlerDetect → 403).
Copy their user agent from the dblog into /admin/config/system/shy_one_time, one per line. Matches get a 302 to /user/login and the token survives.
Matching is a case-insensitive substring. A pattern like “Mozilla” matches real browsers, and those users can never reset their password.
A link that survives a third-party fetch can still be used by that third party, and the user agent is a header anyone can fake. Single-use links exist to limit the damage when a reset URL leaks.