shipcheck

What an App Store rejection actually costs

Updated September 6, 2026 · published by Baker Ventures LLC · sources cited inline

The fix is never the cost. The cycle is. A privacy-manifest rejection takes about four minutes to fix once you know which package caused it. Finding out costs a build, an upload, a wait, and a message that names a guideline rather than a file.

Price a single round trip honestly: 20 to 40 minutes of EAS build, plus upload and processing, plus one to three days in the review queue, plus the context-switch cost of coming back to a project you had mentally shipped. Multiply by the number of iterations, and a launch that was "done on Friday" is live the following Thursday.

The rejections worth pre-checking are the ones where the message does not tell you where to look — privacy manifests, required-reason APIs, background modes, account deletion, permission strings. Those are configuration, they are deterministic, and a machine can find them before you build.

The arithmetic of a cycle

StageTypical cost
Realise you have been rejected, read the message10 minutes
Work out what it means and which file is responsible20 minutes to several hours
Make the change5 minutes
Build (EAS or local archive)20–40 minutes
Upload and processing10–30 minutes
Wait in review1–3 days
Context switch back in30 minutes

The two bolded rows dominate, and both are worse for configuration rejections than for content ones. A content rejection ("your screenshot shows a competing platform") tells you exactly what to change. A configuration rejection tells you a guideline number, and for a React Native project with 800 packages that is a search problem.

Why React Native and Expo take more cycles

Three structural reasons, none of which are anyone's fault.

The offending code is usually not yours. Required-reason API usage comes from hermes, from Firebase's transitive pods, from image caches and SQLite wrappers. Apple's rule is per-bundle — each executable or dynamic library that uses a required reason API needs a manifest in its own bundle — so your app's manifest cannot cover them. ITMS-91053 in detail.

The generated project is not the source of truth. With Expo's continuous native generation, editing ios/ directly gets overwritten at the next prebuild. A fix that works locally and vanishes on the build server is a whole wasted cycle, and it is a very common one.

Permission strings come from packages. An NSLocationAlwaysAndWhenInUseUsageDescription can appear in your Info.plist because a config plugin put it there, describing a feature you removed six months ago. Apple reads it and asks why an app with no map needs background location. That is a Guideline 5.1.1 or 5.1.5 conversation you did not know you had started.

The rejections a machine can catch before you submit

These are deterministic, they live in files, and there is no judgement involved:

The rejections a machine cannot catch are the judgement ones: whether your app has enough functionality to justify existing (4.2), whether it reads as spam (4.3), whether your subscription paywall is honest (3.1.2). Those need a human, and any tool claiming otherwise is overselling.

Why the second and third cycles happen

The first rejection is unavoidable sometimes. The second and third are usually caused by one of three things.

Fixing the symptom rather than the bundle. Adding a UserDefaults reason to your app's manifest when the usage was in a framework. It looks fixed. It uploads. It fails identically.

Declaring defensively. Adding every reason code in a category "to be safe." Apple's wording is that declared reasons must "accurately reflect your use" and that you may use the API and derived data "for the declared reasons only" — several codes bind you to conditions such as never sending the data off-device. Over-declaring is a misdeclaration. The full reason-code reference.

Not answering the reviewer. A silent resubmission gives the reviewer no reason to look at it differently. A Resolution Center reply that names the clause, states what changed and where, and answers the actual question is materially more likely to clear on the next pass.

What to do instead

  1. Run a static check before you build, not after you are rejected. Everything in the deterministic list above is findable in the repository.
  2. Fix in the right bundle. For dependency-sourced findings, the fix is upstream: update, fork, replace or remove.
  3. Write review notes that pre-empt the obvious question. If you declare background location, explain the user-facing feature that needs it, in the notes, before anyone asks.
  4. Keep a demo account that works and check it the morning you submit. A broken demo login is a Guideline 2.1 rejection and it is entirely self-inflicted.
  5. Reply properly when you are rejected. Cite the clause, state the change, name the file.

That first step is what shipcheck is: a scan that runs inside your own Claude Code session, reads the project locally, cites the exact clause, predicts what the reviewer will say, and names the file. No account, no repository upload, first scan free with real findings. What shipcheck checks.

Questions and answers

How long does it take to fix an App Store rejection?

The fix itself is usually minutes. The cycle is the cost - a new build, a new upload, and another trip through review. Each round trip is typically one to three days of calendar time, and configuration rejections often take more than one round trip because the rejection names a guideline rather than a file.

How many times do apps usually get rejected?

There is no reliable public figure, and any specific number you see quoted is usually a vendor estimate rather than Apple data. What is well documented is that Apple rejects a very large number of submissions annually and that metadata, privacy and completeness issues dominate the reasons.

What is the most common reason apps get rejected?

Across public accounts, the recurring clusters are Guideline 2.1 app completeness including crashes and broken demo accounts, Guideline 5.1.1 privacy and data collection including missing account deletion, Guideline 4.2 minimum functionality, and metadata problems under 2.3. Privacy manifest upload errors sit alongside these as a pre-review blocker.

Can you appeal an App Store rejection?

Yes. You can reply in the Resolution Center, and you can escalate to the App Review Board. Replying with a specific, clause-level explanation of what you changed is far more effective than resubmitting silently, because the reviewer sees your reply attached to the submission.

Do rejections hurt your app's ranking?

There is no evidence that a rejection itself affects App Store ranking. The cost is time and momentum - a delayed launch, a missed campaign date, a marketing push aimed at an app nobody can download yet.

Cite this pageshipcheck. “What an App Store rejection actually costs.” Baker Ventures LLC, September 6, 2026. https://shipcheck.bakerventuresstudio.com/why/what-an-app-store-rejection-actually-costs/