Hi, my team and I are getting an error “Request was rejected because user is not permitted to perform this operation” whenever we try to add HTML to our Ghost blogs. I looked at other reports of the issue and they said Cloudflare might be the problem, so I turned it off and tried but it didn’t solve it. This is a problem that only started last week.
That error message is Ghost’s generic “403” wording, and it hides two very different causes, so a couple of quick checks will tell you which one you’re dealing with.
First, narrow it down. Does it happen for every account on the site, including the Owner or an Administrator, or only for some team members? And does it fail when adding an HTML card in the editor, in Code Injection, or both? If it’s only Contributors or Authors who hit it, look at their role first: some raw-HTML actions are restricted to Editor level and above, and Ghost reports that with exactly this message.
If Owners and Admins get it too, it’s almost certainly not Ghost rejecting the request but something in front of it. Open the browser’s DevTools, Network tab, then try to save again and click the failing request (it’ll be a PUT or POST to /ghost/api/admin/...). Two things to look at: the Server header in the response, and the response body. If the body is Ghost’s own JSON error, it’s a permissions issue inside Ghost. If it’s an HTML page or a bare 403 from nginx, Apache, ModSecurity, LiteSpeed or similar, a web application firewall on your host is blocking any request whose body contains <script> or other HTML. That’s the classic cause of this error, and it’s worth knowing that “turning off Cloudflare” often only pauses the proxy, while a host-level WAF (cPanel, Plesk, Hostinger and most managed panels ship ModSecurity enabled by default) keeps running underneath. The fix there is an exception for /ghost/api/admin/ in whatever firewall is answering, or asking your host to add one.
The fact that it started last week without you changing anything points the same way: WAF rule sets get updated by hosts and CDNs on their own schedule, and a new rule that trips on inline scripts would produce exactly this.
If you can share who’s hosting the site and what that failing request returns, it should be a quick one to pin down.