RocketChat/Rocket.Chat · warning · Error

Invalid status code

Error message

Invalid status code

What it means

Internal marker thrown by POST /api/v1/livechat/webhook.test when the configured Livechat_webhookUrl answered the sample payload with any final HTTP status other than 200. It never reaches the client: the surrounding catch logs it under the WebhookTest logger and re-throws error-invalid-webhook-response, so 'Invalid status code' only ever appears in server logs/debug output as the reason behind the outer failure.

Source

Thrown at apps/meteor/server/api/v1/omnichannel/webhooks.ts:88

			} as ExtendedFetchOptions;

			const webhookUrl = settings.get<string>('Livechat_webhookUrl');

			if (!webhookUrl) {
				return API.v1.failure('Webhook_URL_not_set');
			}

			try {
				logger.debug({ msg: 'Testing webhook', webhookUrl });
				const request = await fetch(webhookUrl, options);
				const response = await request.text();

				logger.debug({ msg: 'Webhook response', response });
				if (request.status === 200) {
					return API.v1.success();
				}

				throw new Error('Invalid status code');
			} catch (error) {
				logger.error({ msg: 'Error testing webhook', err: error });
				throw new Error('error-invalid-webhook-response');
			}
		},
	},
);

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Replay the test yourself: POST the sample LivechatSession payload with header X-RocketChat-Livechat-Token to your endpoint and confirm it returns exactly HTTP 200
  2. If your service legitimately answers 201/204 on success, add a wrapper route that answers 200 for this integration
  3. Check the receiver's own logs for crashes on the sample payload (it contains visitor/agent/messages objects with ISO dates)

Example fix

// before (Express handler answering 201)
res.status(201).json({ ok: true });

// after (Rocket.Chat webhook.test requires 200)
res.status(200).json({ ok: true });
Defensive patterns

Strategy: validation

Validate before calling

# validate your receiver answers 200 before wiring it into Rocket.Chat
curl -i -X POST https://receiver.example/webhook \
  -H "X-RocketChat-Livechat-Token: $LIVECHAT_SECRET_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"type":"LivechatSession","_id":"test"}'
# the first line must read: HTTP/1.1 200

Prevention

When it happens

Trigger: POST /api/v1/livechat/webhook.test (needs view-livechat-webhooks permission and Livechat_webhookUrl set) while the receiver endpoint replies 201/202/204, a 4xx auth rejection, or a 5xx — fetch follows redirects, so the final status after any 3xx hop is what counts.

Common situations: Receiver returns 201 Created or 204 No Content on success — Rocket.Chat insists on exactly 200; receiver rejects the X-RocketChat-Livechat-Token header (secret mismatch) with 401/403; framework default error pages (502 from a proxy) when the handler crashes on the sample payload's shape.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/79364633f8015bd2. Report an issue: GitHub.