BookStackApp/BookStack · error · UserTokenExpiredException
Token of id {$entry->id} has expired.
Error message
Token of id {$entry->id} has expired. What it means
UserTokenExpiredException raised by checkTokenAndGetUserId when the token row exists but entryExpired() determines the created_at timestamp is older than the service's expiry window (e.g. 336 hours for invites). Input at fault: a token whose lifetime has elapsed.
Source
Thrown at app/Access/UserTokenService.php:50
->delete();
}
/**
* Get the user id from a token, while checking the token exists and has not expired.
*
* @throws UserTokenNotFoundException
* @throws UserTokenExpiredException
*/
public function checkTokenAndGetUserId(string $token): int
{
$entry = $this->getEntryByToken($token);
if (is_null($entry)) {
throw new UserTokenNotFoundException('Token "' . $token . '" not found');
}
if ($this->entryExpired($entry)) {
throw new UserTokenExpiredException("Token of id {$entry->id} has expired.", $entry->user_id);
}
return $entry->user_id;
}
/**
* Creates a unique token within the email confirmation database.
*/
protected function generateToken(): string
{
$token = Str::random(24);
while ($this->tokenExists($token)) {
$token = Str::random(25);
}
return $token;
}
View on GitHub (pinned to 18f8469a1c)
Solutions
- Have the user request a new invite or password-reset link
- If needed, admin can extend expiryTime in the token service or regenerate the token
- Inform the user links are time-limited and must be used promptly
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at app/Access/UserTokenService.php:50 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/800394cecaef75ea.
Report an issue: GitHub.