shipcheck

Guideline 2.5.4 — background modes without a feature

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

Guideline 2.5.4 rejects apps that declare a background mode the app does not genuinely need. For location specifically, Apple's position is that declaring the location background mode for purposes such as tracking users or other people — without a legitimate, user-facing persistent-location feature — is not appropriate.

The React Native and Expo version of this rejection is almost always accidental. Nobody set out to claim background location. A config plugin added UIBackgroundModes when a package was installed, the feature that needed it was removed, the package stayed, and the declaration shipped. App Review reads the Info.plist in the binary, not your intent.

The fix has to be made where the file is generated, not where you can see it.

How to find out what you are actually declaring

Read the generated Info.plist, not the one in your repository:

# after a prebuild
/usr/libexec/PlistBuddy -c "Print :UIBackgroundModes" ios/*/Info.plist 2>/dev/null

# every purpose string you ship
/usr/libexec/PlistBuddy -c "Print" ios/*/Info.plist | grep -i 'UsageDescription' -A1

Then, for each entry, answer one question in one sentence: which user-facing feature stops working if this is removed? If you cannot answer it, App Review will ask and you will not have a better answer then.

The Expo-specific trap

With continuous native generation, ios/ is a build artefact. The sequence that costs an entire extra cycle:

  1. Rejected under 2.5.4.
  2. You open ios/YourApp/Info.plist and delete the location background mode.
  3. It builds and runs correctly locally.
  4. You push; EAS runs prebuild; the plugin re-adds the key.
  5. Rejected again, identically.

Fix it at the source. Remove the package, or configure the plugin. Anything expressed only in a generated directory does not exist as far as the build server is concerned. Why RN and Expo fail differently.

If you genuinely need background location

Do three things before you submit.

Make the feature obvious in the app. There should be a screen a reviewer can reach that visibly depends on background location, and the app should degrade gracefully rather than break if the permission is declined — Guideline 5.1.5 addresses apps that are non-functional without location.

Stage the permission request. Ask for "When In Use" first, behind a plain-language primer screen explaining what the app does with it, then escalate to "Always" with a rationale. Demanding "Always" at first launch is a rejection pattern in its own right.

Write it into the Review Notes. Name the feature, say where in the app to find it, and explain why it needs to run in the background. A reviewer who has to guess will guess conservatively.

The Play side is a separate, larger hurdle

Android's ACCESS_BACKGROUND_LOCATION requires a Permissions Declaration in Play Console: a written justification that background location is core functionality, plus a demonstration video showing the feature in use. Google's guidance is that apps should use the least invasive option that satisfies the use case, and a background-location request that a foreground-only flow could satisfy is likely to be refused.

Two separate reviews, two separate evidence bundles, one shared prerequisite: the feature has to be real and visible.

What a pre-submission check should catch

All five are deterministic and all five are findable before a build. That is what shipcheck scans for, locally, inside your own Claude Code session. What it checks.

Questions and answers

What is App Store Guideline 2.5.4?

It addresses multitasking APIs, and states that apps should only declare background modes when the app genuinely requires the described background services. Declaring the location background mode for purposes such as tracking users or other people, when the app has no legitimate persistent-location feature, is not appropriate.

Why did my Expo app get rejected for background location I do not use?

Because a config plugin added UIBackgroundModes with location, or added a location purpose string, when you installed a package. App Review reads the shipped Info.plist rather than your intent. If the feature was removed but the package kept, the declaration remains.

How do I remove a background mode from an Expo app?

Remove it at the source. Uninstall the package that adds it, or adjust the config plugin options in app.json or app.config.js. Editing ios/YourApp/Info.plist directly does not survive prebuild, so the change will vanish on the next EAS build.

Does declaring background location require anything else?

On iOS you should be prepared to explain the user-facing feature in Review Notes. On Google Play, ACCESS_BACKGROUND_LOCATION requires a separate Permissions Declaration in Play Console with a demonstration video and evidence that it is core functionality.

Cite this pageshipcheck. “Guideline 2.5.4 — background modes without a feature.” Baker Ventures LLC, September 6, 2026. https://shipcheck.bakerventuresstudio.com/rejections/guideline-2-5-4-background-modes/