laravel/framework · error · UnexpectedValueException
User must implement CanResetPassword interface.
Error message
User must implement CanResetPassword interface.
What it means
Thrown by PasswordBroker::getUser() when the user retrieved by credentials does not implement the Illuminate\Contracts\Auth\CanResetPassword contract. The password reset broker calls getEmailForPasswordReset() and getRememberTokenName()-style methods on the user, so the contract is required for the reset flow.
Solutions
- Make the User model implement Illuminate\Contracts\Auth\CanResetPassword and use the Illuminate\Auth\Passwords\CanResetPassword trait.
- Extend Illuminate\Foundation\Auth\User (which already wires the trait and contract).
- Ensure the auth provider's 'model' points at a class that satisfies the contract.
- If using a non-Eloquent user, implement getEmailForPasswordReset() and sendPasswordResetNotification() manually.
Example fix
// before
use Illuminate\Database\Eloquent\Model;
class Member extends Model {} // no CanResetPassword
// after
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Auth\Passwords\CanResetPassword;
class Member extends Model implements CanResetPasswordContract
{
use CanResetPassword;
} Defensive patterns
Strategy: type-guard
Validate before calling
// PHP — assert the user model satisfies the contract before reset flow
if (! is_subclass_of($userModel, \Illuminate\Contracts\Auth\CanResetPassword::class)) {
throw new \RuntimeException("{$userModel} must implement CanResetPassword to support password reset.");
}
Password::broker()->sendResetLink($credentials); Type guard
function userSupportsReset(string $modelClass): bool {
return is_subclass_of($modelClass, \Illuminate\Contracts\Auth\CanResetPassword::class);
} Try / catch
try {
Password::broker()->sendResetLink($credentials);
} catch (\UnexpectedValueException $e) {
report('User model does not implement CanResetPassword: '.$e->getMessage());
return back()->withErrors(['email' => 'Password reset is not available for this account type.']);
} Prevention
- Extend Illuminate\Foundation\Auth\User or apply the CanResetPassword trait + contract.
- Keep the provider 'model' pointed at a contract-compliant class.
- Add a static-analysis rule (PHPStan) for the CanResetPassword contract.
When it happens
Trigger: Running a password reset (Password::sendResetLink / Password::reset) where the resolved user model class does not implement CanResetPassword (typically by failing to extend Illuminate\Foundation\Auth\User or Illuminate\Database\Eloquent\Model + the trait).
Common situations: A custom User model that extends a bare Eloquent\Model without the Illuminate\Auth\Passwords\CanResetPassword trait and the CanResetPassword contract; swapping the auth provider to return a different DTO/user class that lacks the contract; legacy upgrades where the contract was added in a newer version.
Related errors
- Password resetter [ ] is not defined.
- Auth driver [ ] for guard [ ] is not defined.
- Auth guard [ ] is not defined.
- Authentication user provider
- Cookie jar has not been set.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/f1e51384f08e8a4e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Auth/Passwords/PasswordBroker.php:183
return $user;
}
/**
* Get the user for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword|null
*
* @throws \UnexpectedValueException
*/
public function getUser(#[\SensitiveParameter] array $credentials)
{
$credentials = Arr::except($credentials, ['token']);
$user = $this->users->retrieveByCredentials($credentials);
if ($user && ! $user instanceof CanResetPasswordContract) {
throw new UnexpectedValueException('User must implement CanResetPassword interface.');
}
return $user;
}
/**
* Create a new password reset token for the given user.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @return string
*/
public function createToken(CanResetPasswordContract $user)
{
return $this->tokens->create($user);
}
/**
* Delete password reset tokens of the given user.View on GitHub (pinned to e0f6eb3518)