RocketChat/Rocket.Chat · error · Meteor.Error

error-authToken-param-not-valid

error-authToken-param-not-valid

Error message

The required "authToken" header param is missing or invalid.

What it means

Thrown by POST /api/v1/push.token when the request reaches the handler without an x-auth-token header. Although the endpoint is authRequired (so you authenticated somehow), this specific handler re-reads the raw login token from the header and hashes it with Accounts._hashLoginToken before registering the device token with the push gateway — if the header is absent (query-param style auth, a proxy stripping it), the hash cannot be computed.

Solutions

  1. Send both headers on every push.token call: X-User-Id and X-Auth-Token with the raw login token / personal access token
  2. If a proxy sits in front, verify it forwards X-Auth-Token (curl -v through the proxy to confirm)
  3. Check the client isn't switching to an auth mode (cookie/bearer) that drops the header right before this call

Example fix

// before
await fetch(`${url}/api/v1/push.token`, { method: 'POST', body: JSON.stringify({ type: 'apn', value: deviceToken, appName: 'myapp' }) });

// after
await fetch(`${url}/api/v1/push.token`, {
  method: 'POST',
  headers: { 'X-User-Id': uid, 'X-Auth-Token': authToken, 'Content-Type': 'application/json' },
  body: JSON.stringify({ type: 'apn', value: deviceToken, appName: 'myapp' }),
});
Defensive patterns

Strategy: validation

Validate before calling

if (!headers.has('X-Auth-Token')) throw new Error('push.token requires the X-Auth-Token header');
await fetch(`${url}/api/v1/push.token`, {
  method: 'POST',
  headers: { ...headers, 'X-User-Id': uid, 'X-Auth-Token': authToken, 'Content-Type': 'application/json' },
  body: JSON.stringify({ type, value, appName }),
});

Try / catch

catch 'error-authToken-param-not-valid' and fail fast with a configuration error pointing at the auth headers — retrying without adding x-auth-token cannot succeed.

Prevention

When it happens

Trigger: POST /api/v1/push.token with body { type, value, appName } authenticated via userId/authToken query params or a bearer scheme that leaves x-auth-token unset; a reverse proxy or HTTP/2 client lowercasing/dropping custom headers; sending X-User-Id but forgetting X-Auth-Token.

Common situations: Mobile SDK code that authenticates REST calls through query params or a session cookie and then calls push.token; curl scripts copied with only the user-id header; corporate proxies stripping non-standard headers.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/push.ts:176

					required: ['success', 'result'],
				}),
				400: validateBadRequestErrorResponse,
				401: validateUnauthorizedErrorResponse,
				403: validateForbiddenErrorResponse,
			},
			body: isPushTokenPOSTProps,
			authRequired: true,
		},
		async function action() {
			const { id, type, value, appName, voipToken } = this.bodyParams;

			if (voipToken && !id) {
				return API.v1.failure('voip-tokens-must-specify-device-id');
			}

			const rawToken = this.request.headers.get('x-auth-token');
			if (!rawToken) {
				throw new Meteor.Error('error-authToken-param-not-valid', 'The required "authToken" header param is missing or invalid.');
			}
			const authToken = Accounts._hashLoginToken(rawToken);

			const result = await Push.registerPushToken({
				...(id && { _id: id }),
				token: { [type]: value } as IPushToken['token'],
				authToken,
				appName,
				userId: this.userId,
				...(voipToken && { voipToken }),
			});

			return API.v1.success({ result: cleanTokenResult(result) });
		},
	)
	.delete(
		'push.token',
		{

View on GitHub (pinned to b2c16d5842)