flarum/framework · error · Exception
Invalid auth signature provided.
Error message
Invalid auth signature provided.
What it means
The realtime websocket controller validates the client's signature by computing hash_hmac('sha256', signature, appSecret) and comparing it to the auth_signature query param; any mismatch throws an Exception with 'Invalid auth signature provided.'
Solutions
- Regenerate the client signature as hash_hmac('sha256', signature, appSecret) using the same secret as the server's SocketSettings.
- Ensure the server's configured app secret matches the one distributed to clients (sync config across instances).
- Log the computed vs received auth_signature server-side (carefully, without leaking secrets) to compare values.
- Check that the auth_signature query parameter survives URL encoding and proxying intact.
- Update clients after any secret rotation and retry the connection.
Example fix
// before
const sig = crypto.createHash('sha256').update(payload).digest('hex');
// after
const sig = crypto.createHmac('sha256', appSecret).update(signature).digest('hex'); Defensive patterns
Strategy: try-catch
Validate before calling
const expected = crypto.createHmac('sha256', appSecret).update(signature).digest('hex'); if (expected !== authSignature) { /* abort before connecting */ } Try / catch
try { validateSignature($request); } catch (Exception $e) { // close connection with 401-style error; log mismatch without leaking secrets } Prevention
- Share the app secret through one config source across client and server
- Use HMAC of the signature payload, not a plain hash
- URL-encode query params properly when connecting
- Rotate secrets atomically across all instances
When it happens
Trigger: A websocket connection request (handleRequest -> validateSignature) whose auth_signature query parameter is missing, truncated, URL-encoded incorrectly, or computed with a different key than the configured appSecret.
Common situations: Client and server using different app secrets (stale config or multi-instance mismatch); client hashing the wrong payload or using plain secret comparison; query param mangled by proxies; clock/nonce handling changes between client versions.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Incorrect password
- Paths are not possible in websocket connections.
- $errno, $errstr, $errfile:$errline
- [$errno] $errstr in $errfile:$errline
- Halt signal received, killing to restart.
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/35a8efa2152720ed.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/realtime/src/Websocket/Connection/Controller.php:147
$params = Arr::except($request->getQueryParams(), [
'auth_signature', 'body_md5', 'appId', 'appKey', 'channelName',
]);
if ($this->buffer !== '') {
$params['body_md5'] = md5($this->buffer);
}
ksort($params);
$signature = "{$request->getMethod()}\n{$request->getUri()->getPath()}\n".Pusher::array_implode('=', '&', $params);
/** @var SocketSettings $settings */
$settings = resolve(SocketSettings::class);
$authSignature = hash_hmac('sha256', $signature, $settings->appSecret);
if ($authSignature !== $request->getQueryParams()['auth_signature']) {
throw new Exception('Invalid auth signature provided.');
}
}
protected function sendAndClose(ConnectionInterface $conn, mixed $response): void
{
if ($response instanceof Collection) {
$response = new JsonResponse($response->toArray());
}
if (is_array($response)) {
$response = new JsonResponse($response);
}
if (! ($response instanceof Response)) {
$response = new Response($response);
}
$conn->send(Message::toString($response));
$conn->close();
}View on GitHub (pinned to 4b939f6853)