App Store

    App Store Rejection Guideline 2.1 Performance (Fix)

    Xcode Organizer symbolicating an App Store review crash log next to a Guideline 2.1 performance rejection in the Resolution Center.

    A Guideline 2.1 rejection means Apple found your app incomplete or not performing correctly during review, most often a crash, a bug, a missing demo account, or a failure to connect on Apple's IPv6-only review network. To fix it, read the crash log Apple attaches, symbolicate it with your build's dSYM to find the failing code, and reproduce the issue on a real device. If the app cannot connect during review, the usual cause is IPv4-only networking, since Apple tests on IPv6. Provide working demo credentials and remove any placeholder content before resubmitting.

    Short answer

    Guideline 2.1 is Apple's app-completeness and performance rule, so a rejection here means the app crashed, had a bug, was incomplete, or could not be fully exercised by the reviewer. Per Apple's App Store Review Guidelines, the app must be complete, functional, and stable, with working demo credentials where needed. To fix a crash, read the attached crash log and symbolicate it with the matching dSYM in Xcode, which turns memory addresses into function names and finds the failing line. If the failure is a network one, it is usually because Apple reviews on an IPv6-only network and the app relies on IPv4, which you fix by using high-level networking APIs and avoiding hardcoded IPv4 addresses.

    What Guideline 2.1 Performance means

    Guideline 2.1, App Completeness, requires that the app you submit is the finished product: it runs without crashing, its features work, it contains no placeholder content or broken links, and the reviewer can fully use it. A 2.1 rejection is Apple saying the app did not meet that bar during review, usually because something failed or could not be reached.

    The category is broad on purpose, covering everything from a hard crash to a login the reviewer could not get past. That breadth is why the first step is always to read the specific rejection text and any attached logs, since 2.1 itself does not tell you the cause, only that completeness or performance was the problem.

    How to read Apple crash logs

    When a 2.1 rejection involves a crash, Apple usually attaches a crash log in the Resolution Center, and reading it starts with symbolication. A raw crash log lists memory addresses rather than function names, so you symbolicate it with the dSYM file that matches the exact build you submitted, which turns those addresses into readable file, method, and line references.

    The fastest route is Xcode. Add the crash log to the Xcode Organizer, or open it alongside the matching dSYM, and Xcode symbolicates it for you. Then read from the top of the crashing thread: the exception type, such as a memory access error or an abort, and the backtrace that shows which of your methods led to the crash. Focus on the first frames inside your own code, since those are usually where the fix belongs, and keep the dSYM for every release so you can always symbolicate later.

    IPv6 network bugs

    If your app is rejected for not connecting or crashing on launch and you cannot reproduce it, the cause is often IPv6. Apple reviews apps on an IPv6-only network, so an app that assumes IPv4, hardcodes an IPv4 address, or uses a library that does, can fail during review while working fine on your own dual-stack network.

    The fix is to stop depending on IPv4. Use high-level networking APIs such as URLSession, which handle IPv6 for you, connect to servers by name rather than by a hardcoded IP address, and avoid any IPv4-only literals or assumptions in your code and dependencies. Apple documents supporting IPv6-only networks, and testing on a NAT64 network, which you can set up from a Mac, lets you reproduce the reviewer's environment before you resubmit.

    The most common 2.1 causes

    Most 2.1 rejections come from a short list of issues. The table below maps each common cause to how it shows up in the rejection and the fix that resolves it.

    CauseHow it shows upFix
    Crash on launch or useAn attached crash logSymbolicate, fix, and retest on device
    IPv6-only failureCannot connect on the review networkUse high-level APIs, no IPv4 literals
    Missing demo accountReviewer cannot log inProvide working demo credentials
    Placeholder contentApp looks incompleteReplace with real, final content
    Broken links or featuresA non-functional elementFix it before resubmitting

    Read your rejection against this list first. A crash points you to the log and symbolication, a connection failure points you to IPv6, and a note that the reviewer could not proceed usually points to a missing demo account rather than a code bug at all.

    The demo account trap

    A very common 2.1 rejection has nothing to do with a crash: the reviewer could not get past your login. If your app requires an account, you must provide working demo credentials in the App Review Information section, and they must stay valid throughout review. An expired, rate-limited, or mistyped demo login reads to the reviewer as an app they simply cannot use.

    Avoid this by creating a dedicated, stable review account that is not subject to expiry or usage limits, and by testing those exact credentials on a clean device before submitting. If any part of the app needs hardware, a code, or a specific setup to demonstrate, include clear notes and, where possible, a short demo video, so the reviewer can reach every feature.

    Fix and resubmit checklist

    Work through the issue methodically rather than resubmitting hopefully. The checklist below covers the steps from reading the log to confirming completeness.

    CheckActionDone?
    Crash logSymbolicate it with the matching dSYM[ ]
    ReproduceTest on a real device, not only the simulator[ ]
    IPv6Test on an IPv6 or NAT64 network[ ]
    Demo accountAdd stable, working credentials in App Review Information[ ]
    CompletenessRemove placeholders and fix broken links[ ]

    The two steps people skip most are reproducing on a real device, since the simulator hides device-only and network-only crashes, and testing on an IPv6 network. Doing both before you resubmit is what prevents a second 2.1 rejection for the same underlying cause.

    Writing the reviewer note

    When you resubmit, a short, specific note in App Review Information helps. State what you fixed, name the exact issue if you know it, and point the reviewer to where to verify it. If the rejection was an IPv6 or environment problem you could not initially reproduce, say what you changed and that you tested on an IPv6 network.

    Keep it factual and brief. If you believe the rejection was a genuine mistake, for example the crash log points to something outside your app, you can explain that calmly with the evidence, but in most 2.1 cases the faster path is to fix the reproducible issue and describe the fix rather than to argue.

    What 2.1 does not cover

    Guideline 2.1 is about completeness and stability, not security, so a build that no longer crashes can still be rejected or pulled for a separate security or privacy issue. Permissions the app cannot justify, cleartext traffic, or a secret embedded in the binary are grounds for a different rejection entirely.

    On that separate front, a scanner like PTKD.com analyzes your app build and reports findings ordered by severity and mapped to OWASP MASVS, so you catch those issues before submission. To be clear about the boundary: PTKD does not read crash logs, fix IPv6 bugs, or resolve a 2.1 rejection. It addresses the security and privacy findings that are a common, separate reason apps get rejected.

    What to take away

    • Guideline 2.1 means the app was incomplete or did not perform: a crash, a bug, a missing demo account, or an IPv6 connection failure.
    • Read the attached crash log by symbolicating it with the matching dSYM in Xcode, then fix the first frames in your own code.
    • If the app fails to connect during review, the usual cause is IPv4-only networking; use high-level APIs and test on an IPv6 or NAT64 network.
    • Provide stable, working demo credentials and remove placeholder content and broken links before resubmitting.
    • 2.1 is separate from security; scan your build with PTKD.com for the issues it does not cover.
    • #guideline 2.1
    • #app completeness
    • #crash logs
    • #ipv6
    • #app store review

    Frequently asked questions

    What does an App Store 2.1 performance rejection mean?
    That the app was not complete or did not perform during review under Apple's App Completeness rule. It covers crashes, bugs, placeholder content, broken links, and cases where the reviewer could not fully use the app, such as being unable to log in. Guideline 2.1 itself does not name the cause, so read the rejection text and any attached logs first.
    How do I read and symbolicate Apple crash logs?
    Apple attaches the crash log in the Resolution Center. Symbolicate it with the dSYM that matches the submitted build, most easily by adding it to the Xcode Organizer, which turns memory addresses into file, method, and line references. Read from the top of the crashing thread, note the exception type, and focus on the first frames inside your own code.
    Why does my app fail only during Apple's review?
    Often because Apple reviews on an IPv6-only network and your app relies on IPv4. An app that hardcodes an IPv4 address or uses an IPv4-only library can fail during review while working on your dual-stack network. Use high-level APIs like URLSession, connect by hostname, avoid IPv4 literals, and test on a NAT64 network you can set up from a Mac.
    Why do I need a demo account for a 2.1 rejection?
    Because if your app requires login, the reviewer must be able to get past it. Missing, expired, rate-limited, or mistyped demo credentials read as an app that cannot be used, which is a 2.1 rejection unrelated to any crash. Provide a stable review account in App Review Information and test those exact credentials on a clean device before submitting.
    How do I avoid a repeat 2.1 rejection?
    Reproduce the issue on a real device, since the simulator hides device-only and network-only crashes, and test on an IPv6 or NAT64 network to match the review environment. Confirm the demo account works, remove placeholders and broken links, and add a short reviewer note describing exactly what you fixed and how to verify it.
    Does fixing 2.1 mean my app is secure?
    No. Guideline 2.1 is about completeness and stability, not security. A build that no longer crashes can still be rejected or pulled for unjustified permissions, cleartext traffic, or embedded secrets. A scanner like PTKD.com (https://ptkd.com) catches those, mapped to OWASP MASVS, but it does not read crash logs, fix IPv6 bugs, or resolve a 2.1 rejection.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free