Skip to content

SignatureVerifier raises ValueError on an empty signing_secret (regression in 3.43.0), breaking apps constructed without a signing secret (e.g. Bolt Socket Mode) #1903

Description

@rlaneth

Reproducible in:

The Slack SDK version

slack_bolt==1.28.0
slack_sdk==3.43.0

(The code that breaks under slack_sdk==3.43.0 works with slack_sdk==3.42.0.)

Python runtime version

Python 3.13.5

OS info

# Linux (sw_vers is macOS-only):
Linux 6.12.94+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.94-1 (2026-06-20) x86_64
Debian GNU/Linux 13 (trixie)

Steps to reproduce:

As of slack_sdk==3.43.0, SignatureVerifier.signing_secret became a property whose setter rejects an empty value, so simply constructing a SignatureVerifier with an empty secret raises. This is a behavior change from 3.42.0 (where construction with an empty secret was allowed), shipped in what looks like a patch/minor release.

  1. Minimal, SDK-only reproduction:

    from slack_sdk.signature import SignatureVerifier
    
    SignatureVerifier(signing_secret="")  # raises in 3.43.0; OK in <= 3.42.0
    Traceback (most recent call last):
      ...
      File ".../slack_sdk/signature/__init__.py", line 29, in __init__
        self.signing_secret = signing_secret
        ^^^^^^^^^^^^^^^^^^^
      File ".../slack_sdk/signature/__init__.py", line 41, in signing_secret
        raise ValueError("signing_secret must not be empty.")
    ValueError: signing_secret must not be empty.
    
  2. Real-world impact via slack_bolt (Socket Mode). A Socket Mode app receives events over a WebSocket and has no HTTP request signature to verify, so it is commonly constructed without a signing secret. App/AsyncApp default request_verification_enabled=True and resolve the secret to "" when none is provided (or SLACK_SIGNING_SECRET is unset), then eagerly build RequestVerification(SignatureVerifier(self._signing_secret)) during __init__. With slack_sdk==3.43.0 this now crashes at construction:

    import os
    os.environ.pop("SLACK_SIGNING_SECRET", None)
    
    from slack_bolt import App
    App(token="xoxb-...")  # raises: ValueError: signing_secret must not be empty.
    
    from slack_bolt.app.async_app import AsyncApp
    AsyncApp(token="xoxb-...")  # same

    Both the sync App and async AsyncApp are affected. The same code paths work unchanged with slack_sdk==3.42.0.

  3. Because most projects pin Slack libraries loosely (e.g. slack-sdk>=3.42), a fresh build/install silently picks up 3.43.0 and a previously-working Socket Mode service fails to start with no code change on the user's side.

Expected result:

Constructing a SignatureVerifier (and, transitively, a Bolt App/AsyncApp without a signing secret) should not raise at construction time, preserving <= 3.42.0 behavior. Request-signature validation is only meaningful when a request is actually verified, so an empty/absent secret could be tolerated at construction and surfaced only if/when verification is attempted (or this guard should ship as a clearly-documented breaking change with an appropriate version bump and migration note).

Actual result:

SignatureVerifier.__init__ raises ValueError: signing_secret must not be empty. as soon as it is instantiated with an empty secret. This breaks any downstream code that constructs it without a secret — most notably Bolt Socket Mode apps, which build the request-verification middleware eagerly and have no use for signature verification.

Metadata

Metadata

Labels

questionM-T: User needs support to use the project

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions