jumpserver/jumpserver · warning · CodeError

Code error

Error message

Code error

What it means

VerifyCode.verify() in apps/common/utils/verify_code.py compares the submitted value against the cached expected code; a mismatch raises CodeError. This is the wrong-code path — the key exists (not expired) but right != code, i.e. the user typed/received a different value.

Source

Thrown at apps/common/utils/verify_code.py:65

        return self.gen_and_send()

    def gen_and_send(self):
        try:
            if not self.code:
                self.code = self.__generate()
            self.__send(self.code)
        except JMSException:
            self.__clear()
            raise

    def verify(self, code):
        right = cache.get(self.key)
        if not right:
            raise CodeExpired

        if right != code:
            raise CodeError

        self.__clear()
        return True

    def __clear(self):
        cache.delete(self.key)

    def __ttl(self):
        return cache.ttl(self.key)

    def __get_code(self):
        return cache.get(self.key)

    def __generate(self):
        code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)
        self.code = code
        return code

View on GitHub (pinned to 6ec464fabd)

Solutions

  1. Trim/normalize the input before verify: verify(user_input.strip())
  2. When resending, inform the user the newest SMS is authoritative (older codes are overwritten in cache)
  3. Catch CodeError and show a retry prompt without revealing which part failed; rate-limit verification attempts to prevent brute force
  4. Check the SMS template renders the full code with no truncation

Example fix

# before
verify_code.verify(code)
# after
from apps.common.utils.verify_code import CodeError
try:
    verify_code.verify(code.strip())
except CodeError:
    return error_response('Incorrect verification code')
Defensive patterns

Strategy: validation

Validate before calling

import re

def normalize_code(raw) -> bool:
    return bool(re.fullmatch(r'\d{4,8}', raw.strip()))

if not normalize_code(user_input):
    return error_response('Enter the digits from the SMS')
verify_code.verify(user_input.strip())

Type guard

def is_plausible_code(value) -> bool:
    import re
    return isinstance(value, str) and bool(re.fullmatch(r'\d{4,8}', value.strip()))

Try / catch

from apps.common.utils.verify_code import CodeError
try:
    verify_code.verify(user_input.strip())
except CodeError:
    attempts += 1
    if attempts >= MAX_ATTEMPTS:
        lock_session()
    return error_response('Incorrect code')

Prevention

When it happens

Trigger: User mistypes the digits; multiple codes requested and the user enters an older one (only the latest is cached); SMS body mangled or truncated by the carrier; frontend sends the code with whitespace or concatenated fields.

Common situations: Typing errors on mobile; stale code from an earlier send still visible in the SMS app; template issues dropping digits; testing with hardcoded wrong values.

Related errors


AI-assisted analysis of jumpserver/jumpserver@6ec464fabd (2026-08-28). Data as JSON: /api/errors/4c7c3b23906512fe. Report an issue: GitHub.