App Rejection Fix

Sample Diagnoses: How We Take a Rejection Apart

5 worked examples showing how we take a rejection or a blocked release apart: what the notice says, what we would check, which root causes are realistic, and what we would recommend. They are written by our team to show the method — no client, app or outcome is implied. Real case studies are published separately, and only with written permission.

Read this first. Everything on this page is an example. These are not customer stories, they are not anonymised versions of real engagements, and none of them claims that an app was approved, reinstated or accepted. We publish them because the method is the thing worth showing — and because a page of invented success stories would be worth nothing to you.

Sample diagnoses

Each one follows the shape of a free initial review: the situation, the message you would be looking at, what we would investigate, the root causes that are actually plausible, and the recommended next step.

Example technical diagnosis — written by our team, not a client case.

Google Play

Google Play: Data safety declaration does not match what the app sends

An Android app with an advertising SDK, a crash reporter and a social login is rejected after an update. The developer filled the Data safety form honestly, describing only the email address collected at sign-up.

The message (sample wording)

Your app has been rejected because the information provided in the Data safety section is incomplete or inaccurate. We found that your app collects and shares data types that are not declared in your Data safety form.

Symptoms

  • The declaration was accurate for the code the team wrote, and the team cannot see what is wrong.
  • Nothing in the app changed in this release except a version bump and one SDK upgrade.
  • Google names no specific data type in the notice.

How we would investigate

  1. Read the merged manifest from a release build, not the source manifest — SDKs add permissions the project never declares.
  2. List every dependency with its resolved version, including transitive ones, and identify which of them collect or transmit anything.
  3. Capture network traffic from a fresh install of the release build, through first launch, sign-up, the ad units and a forced crash.
  4. Compare what actually leaves the device with each of Google’s data types, purposes and “shared with third parties” answers.
  5. Read the privacy policy alongside the form: the two must describe the same app.

Possible root causes

  • An advertising or analytics SDK collects the advertising ID, approximate location or device identifiers, and shares them — none of which the developer declared because the developer never wrote that code.
  • A crash reporter uploads diagnostics containing device and app identifiers, declarable as “Crash logs” and “Diagnostics”, which were left unchecked.
  • The social login returns profile fields (name, photo) that the app stores but that the form does not mention.
  • Data is declared as “collected” but not as “shared”, although the SDK sends it to a third party by design.

Recommended next steps

  • Fix, not appeal: the declaration is genuinely incomplete, and an appeal describing it as complete would be untrue.
  • Decide per data type whether to declare it, configure the SDK to stop collecting it, or remove the SDK.
  • Update the Data safety form and the privacy policy together, then resubmit.
  • Add an SDK-and-declaration check to the release checklist, because the next SDK upgrade can reintroduce exactly this.
Full guide: Data Safety Rejection Get this reviewed for your app Real cause depends on your build — this is a worked example, not a verdict.

Example technical diagnosis — written by our team, not a client case.

Apple App Store

App Store: privacy rejection over permissions, purpose strings and tracking

An iOS app asks for photo library and location access during onboarding and includes an attribution SDK. It is rejected under Guideline 5.1 after several previously accepted releases.

The message (sample wording)

Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage

We noticed that your app requests the user's consent to access their location but does not clarify the use of the location in the purpose string.

Symptoms

  • The same permission prompts shipped in earlier versions without comment.
  • The App Privacy answers in App Store Connect were filled in a year ago and not revisited.
  • The team has added an attribution or measurement SDK since the last privacy review.

How we would investigate

  1. Read every NS*UsageDescription string in the built app and judge each one as a reviewer would: does it say what the app does with the data, in the user’s language?
  2. Trace when each permission is requested — a prompt at launch, before the feature is used, reads as data collection rather than a feature.
  3. Check whether anything in the app or its SDKs meets Apple’s definition of tracking, and whether App Tracking Transparency is implemented correctly if so.
  4. Verify the App Privacy answers against the same SDK inventory, and check privacy manifests and required-reason API declarations for every listed SDK.
  5. Confirm there is a working account-deletion path if the app creates accounts.

Possible root causes

  • Generic purpose strings (“to improve your experience”) that do not name the feature the data is used for.
  • Permissions requested up front, before the feature that needs them is reachable.
  • An SDK that performs tracking as Apple defines it, without the ATT prompt or with the prompt shown after the SDK has already initialised.
  • App Privacy answers that no longer describe the current SDK set.
  • A missing or incomplete privacy manifest for a listed third-party SDK.

Recommended next steps

  • Fix and resubmit; a reply alone rarely resolves a purpose-string finding because the string is visible in the build.
  • Rewrite each purpose string to name the feature and the use, and move prompts to the point of use.
  • Re-answer App Privacy from the SDK inventory rather than from memory.
  • If a reviewer’s reading looks factually wrong, reply with the specific screen, the exact string and how to reach it — that is a reply, not an appeal.
Full guide: Privacy Rejection (5.1) Get this reviewed for your app Real cause depends on your build — this is a worked example, not a verdict.

Example technical diagnosis — written by our team, not a client case.

Google Play

Android: an update that cannot be uploaded at all

A Flutter app last released two years ago needs a small fix. The build succeeds locally, but Play Console refuses the bundle. There is no rejection message, because there was no review.

The message (sample wording)

Your app currently targets API level 34 and must target at least API level 36 to ensure it is built on the latest APIs optimized for security and performance.

Symptoms

  • The release is blocked at upload, not after review, so there is nothing to appeal.
  • Play Console may show further warnings at the same time: a deprecated Play Billing Library, 16 KB page size compatibility, or developer verification.
  • Raising targetSdk in the build file causes the project to stop compiling.

How we would investigate

  1. Read the declared and resolved versions from the build configuration: target and compile SDK, Android Gradle Plugin, Gradle, Kotlin, the Flutter SDK and every plugin with native code.
  2. Identify which requirements the configuration already fails and which cannot be judged from text at all — 16 KB alignment and signing identity live in the built artefact, not in the config.
  3. Assess the Android 16 behaviour changes against the app: edge-to-edge enforcement, large-screen orientation and resizability, predictive back, background work and notification rules.
  4. Check whether the app monetises, because the Play Billing Library requirement then applies to the same release.
  5. Decide whether an extension request from the Policy status page buys useful time for the plan.

Possible root causes

  • The target API level is simply below the current requirement — a mechanical block with a mechanical fix.
  • The toolchain cascade: compiling against the new SDK forces an AGP, Gradle and Kotlin upgrade that abandoned plugins cannot survive.
  • Native libraries from old plugins are not 16 KB aligned, so a second requirement lands in the same release.
  • The billing dependency is pinned by a wrapper package and is below the required version.

Recommended next steps

  • Treat it as a modernization project, sequenced so one toolchain upgrade satisfies several requirements at once.
  • Replace or fork abandoned plugins before touching application code.
  • Plan device testing for the behaviour changes — layouts, back navigation, split-screen — because everything compiles long before everything works.
  • Use a staged rollout for the first release after the upgrade.
Full guide: Legacy App Update & Modernization Get this reviewed for your app Real cause depends on your build — this is a worked example, not a verdict.

Example technical diagnosis — written by our team, not a client case.

Apple App Store

Apple: subscriptions that load for the developer and not for anyone else

A subscription app shows an empty paywall for TestFlight testers. The same build showed products correctly on the developer’s own device a week earlier.

The message (sample wording)

Products request returned 0 products and 1 invalid product identifier.

Symptoms

  • The paywall renders but is empty; no error is shown to the user.
  • It worked in the sandbox on the developer’s device and stopped working for testers.
  • Nothing in the purchase code changed between the two builds.

How we would investigate

  1. Check the Paid Applications agreement and the banking and tax details first — an incomplete agreement makes every product invalid regardless of the code.
  2. Read each product’s exact status in App Store Connect, and whether that status makes it available in the environment being tested.
  3. Compare the product identifiers in the app against App Store Connect character by character, including the bundle-identifier prefix.
  4. Establish which environment the build is running in and which environment receipt validation points at — sandbox, TestFlight and production do not behave identically.
  5. Confirm the request is made after the product has propagated, and that a failed request is surfaced rather than swallowed.

Possible root causes

  • Agreements, tax or banking details are incomplete or have lapsed, so no product is ever returned.
  • The product is in a state that is not available in the environment under test.
  • A product identifier mismatch — a renamed product, a stale constant, or a different bundle identifier in the build configuration being tested.
  • Receipt validation is pointed at the wrong environment, so purchases appear to fail after they succeed.
  • The app queries products before StoreKit is ready and never retries.

Recommended next steps

  • Work down the layers in order — agreements, configuration, identifiers, StoreKit, environment — rather than re-reading the purchase code.
  • Make failures visible in the app: an empty paywall should report that products could not be loaded.
  • Verify entitlements server-side against the App Store Server API rather than trusting the client.
  • If a reviewer rather than a tester reported the problem, this is a configuration issue and not a Guideline 3.1 judgement — the two need different responses.
Full guide: In-App Purchases Not Working Get this reviewed for your app Real cause depends on your build — this is a worked example, not a verdict.

Example technical diagnosis — written by our team, not a client case.

Apple App Store

Apple: a build that will not upload because of signing and entitlements

A release build archives successfully but is rejected by App Store Connect minutes after upload, with an automated email rather than a review decision.

The message (sample wording)

ITMS-90078: Missing Push Notification Entitlement - Your app appears to include API used to register with the Apple Push Notification service, but the app signature's entitlements do not include the "aps-environment" entitlement.

Symptoms

  • The email arrives automatically; no reviewer has seen the build.
  • Push notifications work in a development build and the capability appears to be enabled in Xcode.
  • The problem often appears right after an account, team or certificate change.

How we would investigate

  1. Separate the four layers before changing anything: certificate, identifier and its capabilities, provisioning profile, and the entitlements actually embedded in the build.
  2. Inspect the entitlements in the archived app itself rather than the project settings — the build is what Apple checks.
  3. Confirm the App ID has the capability enabled and that the profile used for the release was regenerated after that change.
  4. Check which profile the Release configuration actually used, which is frequently not the one the developer assumes.
  5. Distinguish the push entitlement from the APNs key or certificate: one lets the build upload, the other lets notifications send.

Possible root causes

  • The capability was enabled on the identifier but the distribution profile predates the change and was never regenerated.
  • Manual signing selected a profile without the entitlement, while automatic signing on a different machine masked the problem.
  • A framework or SDK links the push APIs even though the app itself does not use them, so the entitlement is required anyway.
  • A team or account change invalidated the certificate and profile chain used by the release configuration.

Recommended next steps

  • Fix the signing chain and upload again; there is no review decision to contest.
  • Regenerate the distribution profile after every capability change, and verify the embedded entitlements in the archive before uploading.
  • If push is genuinely not used, find which dependency links the API and decide whether to remove it or keep the entitlement.
  • Record which certificates and profiles the release pipeline uses, so the next team change does not repeat this.
Full guide: iOS Code Signing & Profiles Get this reviewed for your app Real cause depends on your build — this is a worked example, not a verdict.

Sample diagnosis vs real case study

Sample diagnosis
An illustrative example written by our team to show the structure and the reasoning. No client, app or outcome is implied. Always labelled as a sample.
Real case study
A completed engagement, published with the client’s written permission and approved text, with the actual outcome — good or bad. None are published yet, and we will not invent one to fill the gap.

Common rejection scenarios we review

Drawn from our rejection taxonomy. Each links to the guide that explains the causes and the fix path in detail.

Google Play

Production access rejected

The application for production access after the closed-testing requirement was not approved.
Google Play

More testing required

Google asked for more closed testing before granting production access.
Google Play

Data safety rejection

The Data safety declaration does not match what the app or its SDKs actually collect or share.
Google Play

Reviewer / app access

The reviewer could not sign in or reach restricted functionality; app-access instructions were missing or wrong.
Google Play

App suspended

A suspension is a serious enforcement action that may count as a strike against the developer account.
Google Play

Developer account terminated

The developer account itself was terminated; all apps are removed and publishing is disabled.
Apple App Store

Guideline 2.1 — App Completeness

The build crashed, contained placeholder or unfinished features, or the reviewer could not complete a core flow.
Apple App Store

Guideline 2.3 — Accurate Metadata

Screenshots, description, name, keywords, previews or age rating do not accurately reflect the app.
Apple App Store

Guideline 3.1.1 — In-App Purchase

Digital content, features or subscriptions were unlocked outside In-App Purchase, or IAP items were not reviewable.
Apple App Store

Guideline 4.2 — Minimum Functionality

The app was judged too limited: a repackaged website, marketing app, or content that does not need a native app.
Apple App Store

Guideline 4.3 — Spam / Similar apps

The app was judged too similar to your other apps or to existing apps, or built from a template without meaningful differentiation.
Apple App Store

Guideline 5.1.1 — Data Collection and Storage

Privacy policy, permission purpose strings, data minimisation, mandatory login or App Privacy labels did not meet 5.1.1.

Have a case like these?

Send the notice and we will work through it the same way, on your app rather than on an example. If you later agree to a case study, you decide whether it is anonymous or named.

What happens next: an engineer on our technical team reads the notice you send — not an autoresponder. We work out what it most likely means and what we would check, and reply with that assessment and a recommended next step.

Initial rejection review is free. Technical implementation, if required, is quoted separately.

Get My Free Rejection Review

Free initial review · No payment required · No source code required initially