docusealco/docuseal · error · CanCan::AccessDenied
-32603
-32603
Error message
Forbidden
What it means
The MCP (Model Context Protocol) controller rejected the request and rendered JSON-RPC error code -32603 with message 'Forbidden' over HTTP 403. It fires from the before_action chain: Devise's authenticate_user! (no valid session), verify_mcp_enabled! (feature disabled), or the inline CanCan check can?(:manage, :mcp) failing for the authenticated user. Note that -32603 is the JSON-RPC 'internal error' slot reused here for authorization denials, which can confuse generic MCP clients.
Source
Thrown at app/controllers/mcp/mcp_base_controller.rb:12
# frozen_string_literal: true
module Mcp
class McpBaseController < ActionController::API
wrap_parameters false
before_action :authenticate_user!
before_action :verify_mcp_enabled!
check_authorization
before_action do
raise CanCan::AccessDenied unless can?(:manage, :mcp)
end
rescue_from CanCan::AccessDenied do
render_error(-32_603, 'Forbidden', status: :forbidden)
end
rescue_from ActiveRecord::RecordNotFound do
render_tool_error('Not found')
end
private
def default_url_options
Docuseal.default_url_options
end
def mcp_body
request.request_parametersView on GitHub (pinned to 004a22c1c8)
Solutions
- Confirm MCP is enabled for the instance/account (the verify_mcp_enabled! gate).
- Authenticate with a user whose role grants manage :mcp - check the CanCan ability definitions for :mcp.
- Ensure the MCP client sends credentials on every request, not just the initial handshake.
- When building an MCP client, treat code -32603 with message 'Forbidden' as a terminal auth error, not a retryable internal error.
Defensive patterns
Strategy: validation
Validate before calling
# smoke-test access before registering tools curl -i -b 'session=...' https://app.example.com/mcp # expect 2xx; 403 with -32603 'Forbidden' means stop and fix auth/entitlements first
Type guard
const isMcpForbidden = (err) => err?.code === -32603 && err?.message === 'Forbidden'
Prevention
- Use a dedicated admin-scoped user for MCP integrations
- Verify feature flags before pointing clients at /mcp
- Prefer a dedicated JSON-RPC error code for authz failures so clients can react precisely
When it happens
Trigger: Calling any /mcp route without a valid authenticated session; authenticating as a user whose role lacks the manage :mcp ability; hitting MCP endpoints on an instance where the MCP feature is disabled.
Common situations: Wiring an MCP client (editor assistant, agent) with missing cookies/tokens; self-hosted instances without MCP enabled; roles or plans without MCP entitlements.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21).
Data as JSON: /api/errors/ba00eb0c4d266cc4.
Report an issue: GitHub.