n8n-io/n8n · error · ForbiddenError
403
403
Error message
Forbidden
What it means
Thrown by the credential probe endpoint (POST against the persisted test URL) when credentialsService.probeById() raises CredentialNotFoundError. Same masking pattern as /test: the controller re-throws ForbiddenError() — its default message is the string 'Forbidden' (HTTP 403) — to avoid disclosing whether the credential is missing or merely forbidden.
Source
Thrown at packages/cli/src/credentials/credentials.controller.ts:184
@ProjectScope('credential:read')
async probeCredentials(
req: AuthenticatedRequest,
_res: unknown,
@Param('credentialId') credentialId: string,
) {
try {
const result = await this.credentialsService.probeById(req.user, credentialId);
this.eventService.emit('credentials-probed', {
user: req.user,
credentialId,
outcome: result.outcome,
});
return result;
} catch (error) {
if (error instanceof CredentialNotFoundError) {
throw new ForbiddenError();
}
throw error;
}
}
@Post('/')
async createCredentials(
req: AuthenticatedRequest,
_: Response,
@Body payload: CreateCredentialDto,
) {
const newCredential = await this.credentialsService.createUnmanagedCredential(
payload,
req.user,
);
const project = await this.sharedCredentialsRepository.findCredentialOwningProject(View on GitHub (pinned to 5ac6606e81)
Solutions
- Verify the credential is owned/shared with the current user via GET /credentials before probing.
- Treat a 403 'Forbidden' from the probe endpoint as 'not accessible' and refresh the list.
- Ensure the user has credential:read on the owning project.
Defensive patterns
Strategy: validation
Validate before calling
async function canAccessCredential(credentialId: string) {
const r = await fetch(`/rest/credentials/${credentialId}`);
return r.ok;
}
if (!(await canAccessCredential(id))) {
throw new Error('Credential not accessible; cannot probe');
} Try / catch
try { await fetch(`/rest/credentials/${id}/probe`, { method: 'POST' }); }
catch (e) { if (e.statusCode === 403 && /forbidden/i.test(e.message)) { /* refresh list */ } else throw e; } Prevention
- Verify credential:read on the owning project before probing.
- Treat a generic 403 'Forbidden' from probe as 'not accessible'.
- Do not cache credential access across project moves.
When it happens
Trigger: Probing a credential whose id is unknown or not accessible to req.user; the service raises CredentialNotFoundError and the controller converts it to a generic 403 'Forbidden'.
Common situations: Generic credential types (e.g. Templated Custom Auth) being probed after the user lost access; id from another environment; credential deleted between selection and probe.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- 404
- Maximum number of users reached
- User not found
- Admin cannot reset password of global owner
- Instance owner cannot be deleted.
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/43f255c6c1a7cc40.
Report an issue: GitHub.