TechnitiumSoftware/DnsServer · warning · InvalidOperationException
Time-based one-time password (TOTP) is already enabled for u
Error message
Time-based one-time password (TOTP) is already enabled for user:
What it means
Thrown by User.InitializedTOTP(issuer) when _totpEnabled is already true, meaning TOTP was previously initialized and confirmed via EnableTOTP. Re-initializing would generate a new AuthenticatorKeyUri and orphan the old secret, breaking already-configured authenticator apps, so the library refuses the call. The state check comes after the SSO guard but before any key generation.
Source
Thrown at DnsServerCore/Auth/User.cs:287
_passwordHash = GetPasswordHashFor(newPassword);
}
public void LoadOldSchemeCredentials(string passwordHash)
{
if (_isSsoUser)
throw new InvalidOperationException();
_passwordHashType = UserPasswordHashType.OldScheme;
_passwordHash = passwordHash;
}
public AuthenticatorKeyUri InitializedTOTP(string issuer)
{
if (_isSsoUser)
throw new InvalidOperationException("Time-based one-time password (TOTP) feature is not available for SSO users.");
if (_totpEnabled)
throw new InvalidOperationException("Time-based one-time password (TOTP) is already enabled for user: " + _username);
_totpKeyUri = AuthenticatorKeyUri.Generate(issuer, _username);
return _totpKeyUri;
}
public void EnableTOTP(string totp)
{
if (_isSsoUser)
throw new InvalidOperationException("Time-based one-time password (TOTP) feature is not available for SSO users.");
if (_totpKeyUri is null)
throw new InvalidOperationException("Time-based one-time password (TOTP) was not initialized for user: " + _username);
if (_totpEnabled)
throw new InvalidOperationException("Time-based one-time password (TOTP) is already enabled for user: " + _username);
Authenticator authenticator = new Authenticator(_totpKeyUri);View on GitHub (pinned to d0484b6c1e)
Solutions
- Call DisableTOTP() before calling InitializedTOTP() to rotate the TOTP secret on an already-enabled account.
- Check the user's TOTP state via the session/API before offering the 'initialize' action.
- Build the UI so re-configuration goes through a single 'reset TOTP' flow that disables then re-initializes.
Example fix
// before
var keyUri = user.InitializedTOTP(issuer);
// after
if (user.TotpEnabled)
user.DisableTOTP();
var keyUri = user.InitializedTOTP(issuer); Defensive patterns
Strategy: validation
Validate before calling
if (user.TotpEnabled)
return Conflict("TOTP is already enabled; disable it first to reconfigure.");
var keyUri = user.InitializedTOTP(issuer); Type guard
static bool CanInitializeTotp(User user) => !user.IsSsoUser && !user.TotpEnabled;
Prevention
- Track TOTP state server-side and gate the initialize action.
- Route re-configuration through DisableTOTP first.
- Reflect current TOTP state in the UI before offering setup.
When it happens
Trigger: Calling InitializedTOTP a second time on the same user after EnableTOTP has already completed (i.e. _totpEnabled flipped to true). Common from a UI that lets the user click 'set up TOTP' again, or from a retry loop that does not check current state.
Common situations: User clicks 'reconfigure TOTP' instead of using the dedicated disable-then-re-enable path; a provisioning script runs twice; the authenticator app was lost but the correct recovery flow (DisableTOTP first) was not followed.
Related errors
- Time-based one-time password (TOTP) was not initialized for
- Time-based one-time password (TOTP) is already disabled for
- Time-based one-time password (TOTP) feature is not available
- Invalid time-based one-time password (TOTP) was attempted fo
- Already logged in. Please create a new object to use a diffe
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/f980c36de1e568f7.
Report an issue: GitHub.