RocketChat/Rocket.Chat · error · Error

unauthorized

Error message

unauthorized

What it means

Plain Error thrown by validateChannelParams (the shared validator for POST channels.create) when the calling user lacks permission to create channels: without a teamId you need the 'create-c' permission; with a valid teamId you need 'create-team-channel' on that team's room. Note the quirk that an unknown teamId (team lookup fails) skips the permission check rather than erroring here.

Solutions

  1. Grant the user's role the create-c permission (or create-team-channel for team channels) in Administration > Permissions
  2. Verify the authenticated user with GET /api/v1/me and check its roles before calling create
  3. For team channels, confirm the user is a member of the target team and the role has create-team-channel on that team room
Defensive patterns

Strategy: validation

Validate before calling

const me = await GET('/api/v1/me');
const canCreate = me.roles.includes('admin') || (await GET('/api/v1/permissions', { userId: me._id }))
  .update.some((p) => p._id === 'create-c');

Try / catch

try { await POST('/api/v1/channels.create', body); } catch (e) {
  if (e.message === 'unauthorized') { /* request create-c permission grant */ }
}

Prevention

When it happens

Trigger: POST /api/v1/channels.create by a user whose role lacks create-c; or with teamId supplied and a valid team where the user lacks create-team-channel; commonly a bot/CI token whose role was never granted channel-creation permissions.

Common situations: Newly created API users or bots with minimal roles; self-service guest roles that cannot create channels; attempting to create a channel inside a team the user only joined as a guest; custom role permission resets after an upgrade.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at apps/meteor/server/api/v1/channels.ts:1015

	},
);

async function createChannelValidator(params: {
	user: { value: string };
	name?: { key: string; value?: string };
	members?: { key: string; value?: string[] };
	customFields?: { key: string; value?: string };
	teams?: { key: string; value?: string[] };
	teamId?: { key: string; value?: string };
}) {
	const teamId = params.teamId?.value;

	const team = teamId && (await Team.getInfoById(teamId));
	if (
		(!teamId && !(await hasPermissionAsync(params.user.value, 'create-c'))) ||
		(teamId && team && !(await hasPermissionAsync(params.user.value, 'create-team-channel', team.roomId)))
	) {
		throw new Error('unauthorized');
	}

	if (!params.name?.value) {
		throw new Error(`Param "${params.name?.key}" is required`);
	}

	if (params.members?.value && !Array.isArray(params.members.value)) {
		throw new Error(`Param "${params.members.key}" must be an array if provided`);
	}

	if (params.customFields?.value && !(typeof params.customFields.value === 'object')) {
		throw new Error(`Param "${params.customFields.key}" must be an object if provided`);
	}

	if (params.teams?.value && !Array.isArray(params.teams.value)) {
		throw new Error(`Param ${params.teams.key} must be an array`);
	}
}

View on GitHub (pinned to e4b8178b20)