Most Google Play rejections are not about what an app does. They come from what the release file declares: a target API level below the current requirement, native libraries that are not 16 KB aligned, a permission that needs a declaration nobody filed, a foreground service without its type, a debug certificate. All of that can be read from the APK or AAB before you upload it.
This page runs the same analyzer as the APK & AAB analyzer, with the Google Play scenario pre-selected so that the report concentrates on what Play Console will check. Each finding names the rule, shows the evidence it is based on, explains the fix and links to the official Google page that states the requirement. The file is read in your browser and never uploaded.
What it checks
The table lists every check, the severity it reports and the exact condition under which it fires. IDs are stable, so #PLAY-15 in a report always points to the same rule.
| ID | What is checked | Severity | When it fires | Applies to |
|---|---|---|---|---|
PLAY-01 | targetSdkVersion below the Google Play requirement | Will be rejected | Play only. Phones/tablets: targetSdk ≥ 36 from 2026-08-31 (high risk while an extension to 2026-11-01 is possible, if ≥ 35); Wear OS / Automotive ≥ 35; TV ≥ 34; XR ≥ 34. Form factor from required <uses-feature>. | Google Play |
PLAY-02 | 16 KB page size: ELF segments not 16 KB aligned | Will be rejected (from 2027-02-01) | Play only. .so files in lib/arm64-v8a and lib/x86_64 with any PT_LOAD p_align < 0x4000. High risk until 2027-02-01, reject from then. | Google Play |
PLAY-03 | 16 KB page size: uncompressed .so not 16 KB aligned in the ZIP | Will be rejected (from 2027-02-01) | Play, APK only. Uncompressed (STORED) 64-bit .so whose data offset is not a multiple of 16384; skipped when extractNativeLibs="true". High risk until 2027-02-01. | Google Play |
PLAY-04 | Missing 64-bit native libraries | Will be rejected | Play only. armeabi-v7a/armeabi without arm64-v8a, or x86 without x86_64; or an ELF whose class/machine does not match its ABI directory. | Google Play |
PLAY-06 | Debuggable or test-only build | Will be rejected | Play only. application android:debuggable="true" or android:testOnly="true". | Google Play |
PLAY-07 | Package name uses a reserved prefix | Will be rejected | Play only. Package name com.example.*, com.android.* or android.*. | Google Play |
PLAY-08 | SMS or Call Log permissions | Will be rejected | Play only. Any SMS or Call Log permission is requested. | Google Play |
PLAY-09 | QUERY_ALL_PACKAGES permission | High risk | Play only. QUERY_ALL_PACKAGES is requested (high risk: declaration review). | Google Play |
PLAY-10 | All files access | Will be rejected | Play only. MANAGE_EXTERNAL_STORAGE → reject; requestLegacyExternalStorage="true" alone → high risk. | Google Play |
PLAY-12 | REQUEST_INSTALL_PACKAGES permission | High risk | Play only. REQUEST_INSTALL_PACKAGES is requested. DEX evidence of self-update comes in a later version. | Google Play |
PLAY-13 | Background location permission | High risk | Play only. ACCESS_BACKGROUND_LOCATION is requested. | Google Play |
PLAY-16 | Photo and video permissions | Will be rejected | Play only, and only when targetSdk ≥ 33: READ_MEDIA_IMAGES or READ_MEDIA_VIDEO is requested. | Google Play |
SIDE-01 | targetSdkVersion too low to install on new Android versions | Will be rejected | Outside Play. targetSdk < 24 (Android 15+ refuses to install) or < 23 (Android 14+). | Outside Play (sideload) |
SIGN-01 | Signed with an Android debug certificate | Will be rejected | Any signer certificate whose subject CN is "Android Debug" (the SDK debug keystore is CN=Android Debug, O=Android, C=US; framework templates such as React Native use other O values). Reject on Play; high risk outside Play. Google states that Play does not accept apps signed with a debug certificate; that Play identifies them by this subject is likely but not documented. | Google Play / Outside Play (sideload) |
SIGN-03 | Only a v1 (JAR) signature | Will be rejected | APK only. No v2/v3 signature: reject only when targetSdk ≥ 30 (cannot install), high risk below 30; no signature at all is reported separately. | Google Play / Outside Play (sideload) |
PLAY-05 | An APK instead of an Android App Bundle for Google Play | High risk | Play scenario, APK files only. High risk: new apps must be published as an AAB (since August 2021); Google’s pages state the requirement for new apps. Reject for Android TV apps (required <uses-feature android.software.leanback>): Play no longer accepts APK updates for TV apps since 2023-06-30. | Google Play |
PLAY-11 | Accessibility service declared | High risk | Play only. Any <service> protected by BIND_ACCESSIBILITY_SERVICE. Its android:isAccessibilityTool value is read from the service config XML when the resource table resolves it. | Google Play |
PLAY-14 | Exact alarm permission | High risk | Play only. USE_EXACT_ALARM → high risk (only for apps whose core function is an alarm clock or calendar). SCHEDULE_EXACT_ALARM alone → advice (users can deny it). | Google Play |
PLAY-15 | Foreground service types and full-screen intents | High risk | Only when targetSdk ≥ 34. Reject (everywhere): a service declares a foregroundServiceType without its FOREGROUND_SERVICE_<TYPE> permission (it crashes when started). High risk: FOREGROUND_SERVICE without any typed service; on Play also every typed foreground service (Play Console declaration) and USE_FULL_SCREEN_INTENT. Which untyped services are started in the foreground needs DEX (later version). | Google Play / Outside Play (sideload) |
PLAY-17 | Contacts permission (new Play rule) | Advice | Play only. READ_CONTACTS is requested: advice; high risk when targetSdk ≥ 37 (the new minimum-scope rule applies to apps targeting Android 17, enforced from 2027-01-27). | Google Play |
SIDE-02 | Old targetSdk: Play Protect warning on install | High risk | Outside Play. targetSdk more than two API levels below the latest Android release on the check date (the latest level is kept in the rule data). | Outside Play (sideload) |
SIDE-03 | Permissions blocked for sideloaded apps by enhanced fraud protection | High risk | Outside Play. RECEIVE_SMS, READ_SMS, a notification listener or an accessibility service. In the select markets where Google Play Protect’s enhanced fraud protection is active (Google does not publish a full list), installs of such apps from browsers, messaging apps or file managers are blocked. | Outside Play (sideload) |
SIDE-04 | Accessibility service marked as an accessibility tool | High risk | Outside Play. An accessibility service whose config sets isAccessibilityTool="true". Only a hint: whether the app really is a tool for people with disabilities needs a human check. Unknown when the config XML cannot be read. | Outside Play (sideload) |
SIDE-06 | High-risk combination of capabilities | High risk | Outside Play. Three or more of: SYSTEM_ALERT_WINDOW, an accessibility service, SMS permissions, a device admin receiver, a notification listener. | Outside Play (sideload) |
SIDE-07 | No launcher entry | Advice | Outside Play. No activity or activity-alias with MAIN + LAUNCHER (or LEANBACK_LAUNCHER), and no keyboard, wallpaper, accessibility, dream, TV input, home-screen or other system-style component. | Outside Play (sideload) |
SIDE-08 | Split APK shipped as if it were a complete app | Will be rejected | Outside Play, APK only. Reject (cannot install alone): the file is a split (<manifest split>, isFeatureSplit), which fails with INSTALL_FAILED_INVALID_APK "Full install must include a base package"; or a base APK whose <manifest> sets android:isSplitRequired="true" or android:requiredSplitTypes, which fails with INSTALL_FAILED_MISSING_SPLIT. High risk: a base APK flagged only with <application android:isSplitRequired> or the meta-data com.android.vending.splits.required. The installer does not read those, so it may install but is incomplete without its splits (code or resources from the splits can be missing at runtime). | Outside Play (sideload) |
SIDE-09 | Non-standard ZIP structure | High risk | APK only. Duplicate entries, central directory / local header mismatches, unsafe paths, the encryption flag or an unknown compression method → high risk; extra bytes after the archive → advice. | Google Play / Outside Play (sideload) |
SIDE-10 | Android developer verification: what to register | Advice | Outside Play, APK only. Always lists the package name and signing certificate SHA-256 to register. High risk when the signer is the debug certificate or a public AOSP test key, which cannot prove ownership. | Outside Play (sideload) |
SIGN-02 | Signed with a publicly known key | Will be rejected | A signer certificate matches, by SHA-256, a key whose private half is public: the AOSP test certificates (testkey, platform, shared, media, …) or the React Native template’s debug.keystore (also in Expo’s bare template). Reject on Play; high risk outside Play. | Google Play / Outside Play (sideload) |
SIGN-04 | Weak signing key or certificate digest | High risk | RSA key under 2048 bits, a DSA key, or an MD5-based certificate signature → high risk; a SHA-1-based certificate signature → advice. | Google Play / Outside Play (sideload) |
SIGN-05 | Signing certificate expires before 22 October 2033 | Will be rejected | Play only. A signer certificate’s notAfter is before 2033-10-22. APK: reject (the rule applies to the app signing key). AAB: advice only (the AAB carries your upload key; Google signs the app with the app signing key, and the 2033 rule is stated for that key). | Google Play |
SIGN-08 | ZIP alignment and resources.arsc storage | Will be rejected | APK only. Reject only when targetSdk ≥ 30 and resources.arsc is compressed or not 4-byte aligned (cannot install). Other uncompressed entries not 4-byte aligned → advice. | Google Play / Outside Play (sideload) |
PRIV-07 | Cleartext traffic or user-installed CAs trusted | Advice | usesCleartextTraffic="true"; or not declared with targetSdk < 28 (cleartext then allowed by default); or the network security config permits cleartext or trusts user CAs outside <debug-overrides>. Unknown when the config cannot be read and nothing else is found. | Google Play / Outside Play (sideload) |
PROT-01 | App protection (packer / hardening) identified | Advice | Identification only: a commercial app-protection runtime by its library file name, or (weak signal) one very small classes.dex next to large assets. Protecting code is legitimate; this only explains the trade-offs. | Google Play / Outside Play (sideload) |
With the Google Play scenario selected, rules that only matter for sideloading (the SIDE- checks for Play Protect warnings, developer verification and split APKs) are shown as not applicable. Switch to Both if you also distribute outside Play.
The rejection reasons it catches
Target API level (PLAY-01)
Since 2026-08-31, new apps and updates for phones and tablets must target API level 36. An extension until 2026-11-01 can be requested in Play Console; until that date a build at API 35 is reported as high risk rather than as a rejection. Wear OS and Android Automotive OS apps must target 35, Android TV and Android XR apps 34. The tool reads the required uses-feature entries to pick the right threshold. Source: Target API level requirements.
16 KB memory pages (PLAY-02, PLAY-03)
Apps that target Android 15 or higher must support 16 KB page sizes on 64-bit devices. The checks read the ELF program headers of every lib/arm64-v8a and lib/x86_64 library and, in APKs, the ZIP offset of every uncompressed library. Google’s developer documentation states that non-compliant updates cannot be published from 2027-02-01; until then the tool reports high risk with a countdown. Source: Support 16 KB page sizes.
App Bundle and 64-bit code (PLAY-05, PLAY-04)
New apps must be published as an Android App Bundle. If you drop an APK here with the Play scenario, PLAY-05 reminds you of that as high risk, since Google states the requirement for new apps. For Android TV apps it is a rejection: Google Play has not accepted APK updates for TV apps since 30 June 2023. PLAY-04 checks that every 32-bit ABI has its 64-bit counterpart and that each .so really is built for the directory it sits in.
Restricted permissions and declarations (PLAY-08 to PLAY-17)
Several permissions are allowed only for specific core uses and need a declaration form in Play Console: SMS and Call Log, QUERY_ALL_PACKAGES, all files access, REQUEST_INSTALL_PACKAGES, background location, photo and video access, exact alarms and, as a new rule, contacts. A finding here is not a verdict that the permission is forbidden. It means a reviewer will ask why you need it. The usual fix is a narrower API: the SMS Retriever API, <queries>, the Storage Access Framework, the system Photo Picker, the Contact Picker, inexact alarms.
Two dates matter in the coming months. From 2027-01-27, phone account verification is no longer an allowed use of READ_CALL_LOG, and the new contacts rule (PLAY-17) takes effect for apps targeting Android 17. See Policy deadlines and Contacts permissions.
Foreground services and full-screen intents (PLAY-15)
Apps that target API 34 or higher must declare a foregroundServiceType for each foreground service and request the matching FOREGROUND_SERVICE_<TYPE> permission. A typed service without that permission crashes when it starts, so the tool reports it as a rejection in every scenario. On Play, every typed foreground service also needs a declaration in Play Console, and USE_FULL_SCREEN_INTENT is limited to calling and alarm apps. One limit: which untyped services are actually started in the foreground can only be seen in the code (DEX), which a later version will read. Sources: Foreground service requirements, Foreground service types.
Accessibility services (PLAY-11)
An app that declares an accessibility service must complete the AccessibilityService API declaration and show a prominent disclosure. The tool also reads the service’s configuration XML through the resource table and shows whether it claims isAccessibilityTool="true", which is reserved for tools designed primarily for people with disabilities.
Release build and signing (PLAY-06, PLAY-07, SIGN-01 to SIGN-08)
A debuggable or testOnly build is rejected, and so is a package name under com.example, com.android or android. On the signing side the report checks for debug certificates (any CN=Android Debug), keys whose private half is public: the AOSP test keys and the debug keystore shipped in the React Native template, which the template’s release build uses until you configure your own upload key (React Native: publishing to Google Play), RSA keys under 2048 bits, DSA keys and MD5 signatures, a certificate that expires before 22 October 2033, and, for APKs, a v1-only signature and a compressed or misaligned resources.arsc. For an AAB the certificate is your upload key: Google re-signs the app with the app signing key, and the 2033 validity rule is stated for the app signing key, so validity findings on an AAB are only advice. Sources: Sign your app, Play App Signing.
App protection (PROT-01)
Packing and app hardening are legitimate ways to protect your code, and the tool does not treat them as a problem. When it identifies a commercial protection runtime by its library name, it explains the trade-offs that matter for review: packer start-up code can look like malware packers to heuristic scanners, protections that verify their own signature can break under Play App Signing, and Google Play does not allow downloading executable code from outside Play. The finding is advice, not a defect.
What the file cannot tell you
A clean report covers the release file. Play Console reviews more than that, so keep a checklist for the parts no file inspection can see:
- Data safety form: every SDK’s data collection must match what you declare. The report lists the SDKs it can identify from the manifest and version files as a starting point; their own disclosure pages are the authority.
- Privacy policy and account deletion: a public privacy policy link, and an in-app and web way to delete an account if users can create one.
- Store listing: title, icon, screenshots and description must not mislead or impersonate.
- Testing requirements: personal developer accounts created after 2023-11-13 need a closed test with at least 12 testers for 14 days before production access.
- Runtime behavior: the app must behave the same for reviewers and users and must not download executable code from outside Google Play.
The results do not represent Google’s review decision. For source-level hints inside Android Studio, Google also offers Play Policy Insights.
Your file stays on your machine
The page hands the file to a Web Worker that reads only what the checks need: the ZIP directory, the manifest, the resource table and a few referenced XML files, the first bytes of each native library, version files and the signing data. The worker contains no network code, and its own Content-Security-Policy forbids network access. The analytics event sent after an analysis carries only coarse values (file kind, size and duration buckets, the outcome and the number of failed checks), never a file name, package name, hash or content. Details are on the privacy page.
After the report is shown, the worker also computes the SHA-256 of the whole file in 4 MB slices. Next to it is a link that searches that hash on VirusTotal. It is a plain link: nothing is sent until you click it, and even then VirusTotal only receives the hash in the address. Searching by hash is the safe way to look up a build; uploading an unreleased build to a public scanner can share it with third parties.
How to verify it yourself
- Open your browser’s developer tools on the Network tab before choosing a file. Run a check and look at every request. None of them carries your file; apart from this site you should only see Google Fonts and Google Analytics.
- Or load the page, disconnect from the network (or tick Offline in the Network tab) and run the check. It completes, hash included, because nothing has to leave your computer.
FAQ
Does a clean report mean my app will be approved? No. It means nothing in the file triggered a known rule. Declarations, the Data safety form, the store listing and runtime behavior are reviewed separately.
Why is a rule marked “Unknown”?
A value it needs could not be read, for example a targetSdkVersion written as a resource reference, a damaged signing block, or a configuration file the resource table does not resolve. Unknown is not a pass; check that item by hand.
I distribute both on Play and outside it. Which scenario should I pick? Choose Both. The report then also runs the sideloading checks: install-time limits, Play Protect warnings, enhanced fraud protection and Android developer verification.
Can I check against future rules? Yes. Pick a later date in “Check against the rules in force on”. Rules with a known start date, such as the 16 KB requirement on 2027-02-01, change severity accordingly.
How current are the rules? Every rule records the date it was last checked against its official source. A rule older than 90 days is marked as needing review in the report.
Related
- APK & AAB analyzer: the same tool with both scenarios selected, plus a walk-through of every report section.
- Google Play App Rejection Reasons You Can Catch Before Upload: a before-and-after run on a sample bundle, with the Policy status, resubmission and appeal steps.
- Check an APK for Android’s 16 KB Page Size Requirement: PLAY-02 and PLAY-03 step by step.
- Android APK Analysis with REA: JADX, Apktool, ADB and Flutter: go from a finding to the code that caused it.
- AAB to APK and APK Unpack: Extract Assets and Scripts with REA: build a universal APK from an AAB with bundletool.