{"record":{"id":"a782a453fbff0c68","repo":"django/django","slug":"no-s-found-in-value","errorCode":null,"errorMessage":"No \"%s\" found in value","messagePattern":"No \"(.+?)\" found in value","errorType":"exception","errorClass":"BadSignature","httpStatus":null,"severity":"error","filePath":"django/core/signing.py","lineNumber":249,"sourceCode":"            self.__class__.__name__,\n        )\n        self.algorithm = algorithm or \"sha256\"\n        if _SEP_UNSAFE.match(self.sep):\n            raise ValueError(\n                \"Unsafe Signer separator: %r (cannot be empty or consist of \"\n                \"only A-z0-9-_=)\" % sep,\n            )\n\n    def signature(self, value, key=None):\n        key = key or self.key\n        return base64_hmac(self.salt + \"signer\", value, key, algorithm=self.algorithm)\n\n    def sign(self, value):\n        return \"%s%s%s\" % (value, self.sep, self.signature(value))\n\n    def unsign(self, signed_value):\n        if self.sep not in signed_value:\n            raise BadSignature('No \"%s\" found in value' % self.sep)\n        value, sig = signed_value.rsplit(self.sep, 1)\n        for key in [self.key, *self.fallback_keys]:\n            if constant_time_compare(sig, self.signature(value, key)):\n                return value\n        raise BadSignature('Signature \"%s\" does not match' % sig)\n\n    def sign_object(self, obj, serializer=JSONSerializer, compress=False):\n        \"\"\"\n        Return URL-safe, hmac signed base64 compressed JSON string.\n\n        If compress is True (not the default), check if compressing using zlib\n        can save some space. Prepend a '.' to signify compression. This is\n        included in the signature, to protect against zip bombs.\n\n        The serializer is expected to return a bytestring.\n        \"\"\"\n        data = serializer().dumps(obj)\n        # Flag for if it's been compressed or not.","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/django/django/blob/b5388a3a80cafcce2e34196d8e81cf5b48eb33bb/django/core/signing.py#L231-L267","documentation":"`Signer.unsign()` (signing.py:247-249) raises `BadSignature('No \"%s\" found in value' % self.sep)` when the separator (default `':'`) does not appear anywhere in the supplied signed string. Because `unsign` splits on the separator to recover the value and signature, a missing separator means the input is structurally invalid as a signed token.","triggerScenarios":"Calling `signer.unsign(token)` or `signing.loads(token)` with a string that contains no `:` (or whichever custom `sep` the Signer was constructed with). Examples: a truncated token, a raw unsigned value, a token built with a different separator than the verifier uses.","commonSituations":"Client truncated or URL-decoded a signed cookie/query param incorrectly (e.g. the `:` stripped); a signed value constructed with a custom `sep` being verified by a Signer using the default (or vice versa); passing an unsigned plaintext to `loads()`; mismatched separators across `dumps`/`loads` (note: only `Signer.unsign` exposes `sep`; high-level `dumps`/`loads` use the default).","solutions":["Verify the token still contains the separator before calling `unsign`; if the client may mangle it, re-encode/escape at transport boundaries.","Ensure the same `sep` is used to sign and unsign; `Signer` rejects separators matching `[A-z0-9-_=]` for safety, so pick e.g. `'~'`.","Catch `BadSignature` at the call site and treat the input as untrusted/invalid rather than letting it surface as a 500."],"exampleFix":"// before\nvalue = signer.unsign(raw)  # BadSignature: No \":\" found in value\n// after\nif signer.sep not in raw:\n    raise ValueError('not a signed token')\ntry:\n    value = signer.unsign(raw)\nexcept BadSignature:\n    value = None","handlingStrategy":"try-catch","validationCode":"from django.core.signing import BadSignature\n\ndef is_well_formed(token: str, sep: str = ':') -> bool:\n    return bool(token) and sep in token","typeGuard":"def looks_signed(token: str, sep: str = ':') -> bool:\n    return isinstance(token, str) and sep in token and token.count(sep) >= 1","tryCatchPattern":"from django.core.signing import BadSignature\ntry:\n    value = signer.unsign(token)\nexcept BadSignature as exc:\n    # 'No \":\" found in value' means structurally invalid; treat as unsigned\n    value = None","preventionTips":["Use consistent separators across sign and verify (Signer rejects [A-z0-9-_=] separators).","URL-encode signed tokens at transport boundaries so ':' is preserved.","Always catch BadSignature at the trust boundary instead of letting it raise."],"tags":["signing","bad-signature","security","tokens"],"backgroundTag":null,"analyzedSha":"b5388a3a80cafcce2e34196d8e81cf5b48eb33bb","analyzedAt":"2026-08-10T17:37:52.993Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}