jumpserver/jumpserver · error · ValueError

sp_id is 6 bits

Error message

sp_id is 6 bits

What it means

ValueError('sp_id is 6 bits') raised in CMPPConnectRequestInstance.__init__ when the SP identifier provided to the CMPP2.0 SMS gateway is not exactly 6 characters, because the CMPP 2.0 protocol encodes source_addr as a fixed 6-byte field.

Source

Thrown at apps/common/sdk/sms/cmpp2.py:44

    def __init__(self):
        self.command_id = ''
        self.body = b''
        self.length = 0

    def get_header(self, sequence_id):
        length = struct.pack('!L', 12 + self.length)
        command_id = struct.pack('!L', self.command_id)
        sequence_id = struct.pack('!L', sequence_id)
        return length + command_id + sequence_id

    def get_message(self, sequence_id):
        return self.get_header(sequence_id) + self.body


class CMPPConnectRequestInstance(CMPPBaseRequestInstance):
    def __init__(self, sp_id, sp_secret):
        if len(sp_id) != 6:
            raise ValueError(_("sp_id is 6 bits"))

        super().__init__()

        source_addr = sp_id.encode('utf-8')
        sp_secret = sp_secret.encode('utf-8')
        version = struct.pack('!B', 0x02)
        timestamp = struct.pack('!L', int(self.get_now()))
        authenticator_source = source_addr + 9 * b'\x00' + sp_secret + self.get_now().encode('utf-8')
        auth_source_md5 = hashlib.md5(authenticator_source).digest()
        self.body = source_addr + auth_source_md5 + version + timestamp
        self.length = len(self.body)
        self.command_id = CMPP_CONNECT

    @staticmethod
    def get_now():
        return time.strftime('%m%d%H%M%S', time.localtime(time.time()))

View on GitHub (pinned to 6ec464fabd)

Solutions

  1. Set sp_id to exactly the 6-character SP identifier issued by your CMPP gateway provider
  2. Strip whitespace: sp_id = sp_id.strip() before passing it
  3. Double-check you are using sp_id, not src_id or service_id, for this field

Example fix

# before
client = CMPP2SMS(**{'SP_ID': '12345 '})  # 6 chars incl. space? verify

# after
sp_id = settings.CMPP2_SP_ID.strip()
assert len(sp_id) == 6, 'SP ID must be exactly 6 characters'
Defensive patterns

Strategy: validation

Validate before calling

sp_id = settings.CMPP2_SP_ID.strip()
if len(sp_id) != 6:
    raise ValueError(f'sp_id must be 6 chars, got {len(sp_id)}')

Type guard

def is_valid_sp_id(sp_id: str) -> bool:
    return isinstance(sp_id, str) and len(sp_id.strip()) == 6

Prevention

When it happens

Trigger: Constructing a CMPPClient (or CMPP2SMS during send) with an sp_id shorter or longer than 6 characters, e.g. a 5-char test ID or one with trailing whitespace included in length.

Common situations: ISP-provided SP ID entered with whitespace/newline from config files; wrong credential field mapped (using src_id or enterprise code instead of the 6-digit SP ID); typo when transcribing from the ISP's onboarding document.

Related errors


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