RocketChat/Rocket.Chat · error · Error
Invalid integration id or token provided.
Error message
Invalid integration id or token provided.
What it means
Thrown by the WebHookAPI authenticatedRoute when no incoming integration matches the integrationId + token pair from the /hooks/:integrationId/:token URL. Integrations.findOneByIdAndToken returns null, meaning either the id does not exist or the token does not match the stored integration token. The token is URL-decoded before lookup.
Source
Thrown at apps/meteor/server/api/webhooks.ts:378
function integrationInfoRest(): { statusCode: number; body: { success: boolean } } {
incomingLogger.info('Info integration');
return {
statusCode: 200,
body: {
success: true,
},
};
}
class WebHookAPI extends APIClass<'/hooks'> {
override async authenticatedRoute(routeContext: APIActionContext): Promise<IUser | null> {
const { integrationId, token } = routeContext.urlParams;
const integration = await Integrations.findOneByIdAndToken<IIncomingIntegration>(integrationId, decodeURIComponent(token));
if (!integration) {
incomingLogger.info({ msg: 'Invalid integration id or token', integrationId, token });
throw new Error('Invalid integration id or token provided.');
}
routeContext.request.headers.set('x-auth-token', token);
const req = routeContext.request as Request & { integration?: IIncomingIntegration };
req.integration = integration;
return Users.findOneById(req.integration.userId);
}
override shouldAddRateLimitToRoute(options: { rateLimiterOptions?: RateLimiterOptions | boolean }): boolean {
const { rateLimiterOptions } = options;
return (
(typeof rateLimiterOptions === 'object' || rateLimiterOptions === undefined) &&
!process.env.TEST_MODE &&
Boolean(defaultRateLimiterOptions.numRequestsAllowed && defaultRateLimiterOptions.intervalTimeInMS)
);
}View on GitHub (pinned to f9d3ec372b)
Solutions
- Copy the exact webhook URL from the integration record in admin (Integrations > Incoming > Integration URL) and use it verbatim in the upstream service.
- If the token was regenerated, update the upstream webhook URL with the new token.
- Confirm the integration still exists and is not deleted; recreate if necessary.
- Avoid re-encoding the token; pass it as-is in the path.
Example fix
// before - upstream POSTs to a stale URL POST /api/v1/hooks/abcOLD/oldToken123 // after - copy current URL from the integration record POST /api/v1/hooks/<currentId>/<currentToken>
Defensive patterns
Strategy: validation
Validate before calling
const integration = await Integrations.findOneByIdAndToken(id, decodeURIComponent(token));
if (!integration) throw new ClientError('not-found','integration id/token invalid or deleted'); Type guard
function isValidIntegrationRef(id, token) {
return typeof id === 'string' && id.length>0 && typeof token === 'string' && token.length>0;
} Try / catch
try { await POST(webhookUrl, body); }
catch (e) {
if (/Invalid integration id or token/.test(e?.message)) { refreshIntegrationUrl(); return; }
throw e;
} Prevention
- Copy the webhook URL verbatim from the integration record.
- After regenerating a token, update all upstream URLs immediately.
- Avoid re-encoding the token in the path.
When it happens
Trigger: POST/GET to /api/v1/hooks/<integrationId>/<token> where integrationId is wrong/deleted, the token is wrong, or the token was URL-encoded incorrectly (e.g. double-encoded). The integration may also have been deleted or its token regenerated.
Common situations: Integration token regenerated in admin but the upstream webhook still has the old URL. Copy-paste of the webhook URL truncated. Token contains characters that were percent-encoded by the client and the server's decodeURIComponent does not reverse them as expected.
Related errors
- username-required
- Integration payload must be a JSON object, not an array or p
- error-invalid-user
- error-not-allowed
- error-invalid-user
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/573bcd4d62911358.
Report an issue: GitHub.