postalserver/postal · error · Postal::Error
User has OIDC enabled, password resets are not supported
Error message
User has OIDC enabled, password resets are not supported
What it means
HasAuthentication#begin_password_reset (used by the forgot-password flow) refuses to mint a reset token when OIDC is enabled AND the user is OIDC-managed (oidc_uid present) or has no password at all (password_digest blank). For such accounts the identity provider owns authentication, so a Postal-issued password reset would be meaningless or would bypass the IdP.
Source
Thrown at app/models/concerns/has_authentication.rb:39
user = find_by(email_address: email_address)
raise Postal::Errors::AuthenticationError, "InvalidEmailAddress" if user.nil?
raise Postal::Errors::AuthenticationError, "InvalidPassword" unless user.authenticate(password)
user
end
end
def authenticate_with_previous_password_first(unencrypted_password)
if password_digest_changed?
BCrypt::Password.new(password_digest_was).is_password?(unencrypted_password) && self
else
authenticate(unencrypted_password)
end
end
def begin_password_reset(return_to = nil)
if Postal::Config.oidc.enabled? && (oidc_uid.present? || password_digest.blank?)
raise Postal::Error, "User has OIDC enabled, password resets are not supported"
end
self.password_reset_token = SecureRandom.alphanumeric(24)
self.password_reset_token_valid_until = 1.day.from_now
save!
AppMailer.password_reset(self, return_to).deliver
end
private
def clear_password_reset_token_on_password_change
return unless password_digest_changed?
self.password_reset_token = nil
self.password_reset_token_valid_until = nil
end
def validate_password_presenceView on GitHub (pinned to d038eaa8c7)
Solutions
- Reset the password at the OIDC/identity provider instead - that is authoritative for this user
- If the user must become a local account, clear their oidc_uid (and set a password) first, then reset
- Hide the 'forgotten password' link for OIDC-managed accounts in the UI and skip them in reset scripts
- Guard callers with the same condition (oidc.enabled? && (oidc_uid.present? || password_digest.blank?)) before invoking begin_password_reset
Example fix
# before user.begin_password_reset # raises for OIDC-managed users # after if Postal::Config.oidc.enabled? && (user.oidc_uid.present? || user.password_digest.blank?) redirect_to login_path, alert: "This account is managed by single sign-on. Reset your password with your identity provider." else user.begin_password_reset end
Defensive patterns
Strategy: validation
Validate before calling
# before triggering a reset
if Postal::Config.oidc.enabled? && (user.oidc_uid.present? || user.password_digest.blank?)
raise ArgumentError, "#{user.email} is managed by SSO - reset at the identity provider"
end Type guard
def local_password_user?(user) !(Postal::Config.oidc.enabled? && (user.oidc_uid.present? || user.password_digest.blank?)) end
Try / catch
begin user.begin_password_reset(return_to) rescue Postal::Error => e # expected for SSO-managed accounts: inform the user, never fall back to creating a token redirect_to login_path, alert: "This account uses single sign-on. Reset your password with your identity provider." end
Prevention
- Hide forgot-password links and skip reset emails for users with an oidc_uid
- Exclude OIDC-managed users from any admin bulk-reset tooling
- Decide deliberately (and record) whether a user is local or SSO before setting/clearing oidc_uid
- Run a periodic audit for passwordless accounts while OIDC is enabled so they are not accidentally reset
When it happens
Trigger: Someone submits the password reset request (login page 'forgotten password', or admin-triggered reset) for a user that was provisioned via OIDC (has oidc_uid), or for a passwordless account while Postal::Config.oidc.enabled? is true.
Common situations: SSO users clicking the local reset link out of habit; admins running bulk reset scripts against all users including OIDC ones; mixed installs where some users predate OIDC enablement and some do not; passwordless accounts created purely for OIDC.
Related errors
- OIDC cannot be used unless enabled in the configuration
- Error when scanning with rspamd (got #{response.code})
- Invalid email address
- No host was given for the request
- Could not resolve '#{@host}' to any IP address
AI-assisted analysis of postalserver/postal@d038eaa8c7 (2026-08-21).
Data as JSON: /api/errors/0a8d160e86bdea8c.
Report an issue: GitHub.