getredash/redash · error
Not found
Error message
Not found
What it means
Raised by UserResetPasswordResource.post in redash/handlers/users.py when an admin requests a password reset link for a user that exists but is disabled (is_disabled). The 404 deliberately hides disabled accounts rather than revealing their state.
Source
Thrown at redash/handlers/users.py:173
self.record_event({"action": "create", "object_id": user.id, "object_type": "user"})
should_send_invitation = "no_invite" not in request.args
return invite_user(self.current_org, self.current_user, user, send_email=should_send_invitation)
class UserInviteResource(BaseResource):
@require_admin
def post(self, user_id):
user = models.User.get_by_id_and_org(user_id, self.current_org)
return invite_user(self.current_org, self.current_user, user)
class UserResetPasswordResource(BaseResource):
@require_admin
def post(self, user_id):
user = models.User.get_by_id_and_org(user_id, self.current_org)
if user.is_disabled:
abort(404, message="Not found")
reset_link = send_password_reset_email(user)
return {"reset_link": reset_link}
class UserRegenerateApiKeyResource(BaseResource):
def post(self, user_id):
user = models.User.get_by_id_and_org(user_id, self.current_org)
if user.is_disabled:
abort(404, message="Not found")
if not is_admin_or_owner(user_id):
abort(403)
user.regenerate_api_key()
models.db.session.commit()
self.record_event({"action": "regnerate_api_key", "object_id": user.id, "object_type": "user"})
View on GitHub (pinned to ca79fe988d)
Solutions
- Re-enable the user first (POST /api/users/<id> is_disabled=false), then request the reset link.
- Verify the user's disabled state via GET /api/users/<id> before calling.
- If the user should stay disabled, skip the reset entirely.
Example fix
# before
link = client.post(f'/api/users/{uid}/reset_password')['reset_link']
# after
client.post(f'/api/users/{uid}', json={'is_disabled': False})
link = client.post(f'/api/users/{uid}/reset_password')['reset_link'] Defensive patterns
Strategy: validation
Validate before calling
u = client.get(f'/api/users/{uid}')
if u.get('is_disabled'):
client.post(f'/api/users/{uid}', json={'is_disabled': False})
link = client.post(f'/api/users/{uid}/reset_password')['reset_link'] Prevention
- Filter is_disabled users out of admin maintenance runs.
- Re-enable before reset; the 404 intentionally hides disabled accounts.
When it happens
Trigger: POST /api/users/<id>/reset_password where the user record has is_disabled=True (deactivated account).
Common situations: Offboarding flows that disable users while stale admin tooling still tries to reset their password; attempting to reset a password before re-enabling the account.
Related errors
- No cached result found for this query.
- Bad email address.
- Email already taken.
- Must provide current password to update password.
- Incorrect current password.
AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28).
Data as JSON: /api/errors/4d99cb68e87a332a.
Report an issue: GitHub.