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.)
Full guide: what counts as remote code, and what does not
<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.
Full guide: how to word a permission 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.
Full guide: privacy policy requirements and the mismatches that cause rejections
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.
Paste the rejection email and your manifest.json. We read it and tell you which policy we think the reviewer is citing and what we would change — free, no signup, and it is our reading rather than a ruling from Google. We cannot promise approval; that call is Google’s. If the fix turns out to be bigger than a note, we will tell you what it would take.
If you ship Chrome extensions for clients, the review paperwork repeats every time. We prepare it — policy-gap report, per-permission justifications, single-purpose statement, reviewer test path, and data-use notes — from your actual code and manifest. We do not touch your code or submit for you, and Google's decision is Google's.
What you get is the paperwork a reviewer looks for, written against your real permissions — not a promise of approval. Tell us what you ship and how many, using the form above, and we'll scope it.
Privacy is the other place clean code still fails review: Chrome extension privacy policy and Data Use.
Waiting on a review that has not moved? Why reviews stall and what to do.
The Chrome Web Store Submission Kit is the working document we use on client submissions: permission justification lines you adapt per permission, a Data Use worksheet that maps code paths to declared categories, a privacy policy template, listing-copy rules, and a rejection decoder that turns the email wording into a concrete change. 6-page PDF, one-time $19. It is ours — we wrote it and we are paid when you buy it. Everything on this site stays free either way.
Also useful: How to write permission justifications
Also useful: Privacy policy requirements
Also useful: After a rejection: what to change
How this site handles what you send: data and privacy.