Your extension works perfectly and still gets rejected. Most rejections come down to a handful of policy patterns. Here is each common reason, why reviewers flag it, and what to change — so your next submission is not another round trip.
Under Manifest V3, the executable code that ships must be the code that was reviewed. Anything that fetches a remote payload and then executes it at runtime is treated as remotely hosted code. (Sandboxed pages and iframes that run remote content are handled separately by policy — the violation is your extension executing code it downloaded.)
<script> tag that loads JavaScript from an external URL (CDN, your server)eval or new FunctionFetching data (JSON) from a server is fine. The problem is turning what you fetched into executable code.
script-src. Server calls are network requests, not scripts — and note that a cross-origin fetch from your extension generally still needs a matching host_permissions entry, so add the API domain there and keep its responses as data.The most common rejection for functional extensions. If you request access to more sites than your feature needs, reviewers reject it as over-broad.
<all_urls> or *://*/* when the feature only needs a handful of sites (broad access is allowed when it is genuinely required, but it draws a stricter, slower review)https://*.example.com/*) — note that Chrome ignores the path part of a host permission, so narrowing happens at the domain level. If you only act after a user clicks your icon, switch to activeTab. Each permission should map to a visible feature you can point at. If broad access is truly required, say why in the justification field rather than hoping it passes unexplained.Reviewers reject extensions that declare permissions the code never actually uses, or sensitive permissions with no clear justification.
tabs, cookies, history, webRequest, or debugger without a matching featuretabs with activeTab where possible. If a sensitive permission is essential, make its purpose obvious in the code and the listing.An extension can be rejected — or removed after publishing — when the privacy declaration in the dashboard does not match what the code actually does with user data, or when a privacy policy is missing. The disclosure covers collection, use, storage and transfer — data that never leaves the browser still has to be declared.
Every extension must have one narrow, easy-to-understand purpose. A pile of unrelated permissions or features reads as multi-purpose and gets rejected.
Listing-level issues also cause rejections, even when the code is clean.
host_permissions the domains you actually need — and is broad access justified if you kept it?Rejection is not the end — it is a signal about what to change. Fix the item and resubmit; the resubmission gets a fresh review, and review times range from a few days to a few weeks.
Paste your manifest.json and see which of these reasons it is likely to trip — before you submit. Free, runs in your browser.