OpenNHP/opennhp · error

invalid digit count

Error message

invalid digit count: %d

What it means

randomDigits(n) validates that the requested OTP length is positive before allocating the digit buffer and consuming crypto/rand. A zero or negative n produces this error immediately; it is a pure input-validation failure, not a randomness failure. The only current caller, GenerateOTP, passes a configured length.

Solutions

  1. Set a positive OTP length in the server config (e.g. otp_length = 6) and restart nhp-serverd.
  2. Clamp/validate the configured length in the loader: if n <= 0, default to 6.
  3. If calling randomDigits directly, guard with `if n <= 0 { n = 6 }` before invoking.
  4. Add a startup validation that fails fast with a clear message when the configured OTP length is not in 4..12.

Example fix

// before
n := cfg.OTPLength // 0 when unset
otp, err := randomDigits(n)
// after
n := cfg.OTPLength
if n <= 0 {
    n = 6 // sensible default
}
otp, err := randomDigits(n)
Defensive patterns

Strategy: validation

Validate before calling

if cfg.OTPLength <= 0 {
    return errors.New("otp_length must be > 0 in server config")
}

Type guard

func validOTPLength(n int) bool { return n >= 4 && n <= 12 }

Try / catch

otp, err := GenerateOTP()
if err != nil {
    if strings.Contains(err.Error(), "invalid digit count") {
        return fmt.Errorf("check otp_length config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: GenerateOTP (or any direct caller of randomDigits) invoked with n <= 0 — typically an OTP length config value of 0, a negative value, or an unset/zero-valued config field.

Common situations: config.toml missing the otp length setting so Go's zero value (0) is used; a TOML typo like `otp_length = -6`; programmatic use of the keystore API without setting the length.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/baa030d5573bc8a7. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/server/keystore.go:575

		 WHERE created_at < ?
		   AND (used = 1 OR expires_at <= ?)`,
		cutoff, time.Now().Unix(),
	)
	if err != nil {
		return 0, fmt.Errorf("keystore: sweep otp: %w", err)
	}
	n, err := res.RowsAffected()
	if err != nil {
		return 0, fmt.Errorf("keystore: sweep otp rows affected: %w", err)
	}
	return n, nil
}

// ── Helpers ───────────────────────────────────────────────────────────────

func randomDigits(n int) (string, error) {
	if n <= 0 {
		return "", fmt.Errorf("invalid digit count: %d", n)
	}

	buf := make([]byte, n)
	for i := range buf {
		digit, err := rand.Int(rand.Reader, big.NewInt(10))
		if err != nil {
			return "", err
		}
		buf[i] = byte('0') + byte(digit.Int64())
	}
	return string(buf), nil
}

View on GitHub (pinned to 6e04ca5ff0)