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.
| Cause | How it shows up | Fix |
|---|---|---|
| Crash on launch or use | An attached crash log | Symbolicate, fix, and retest on device |
| IPv6-only failure | Cannot connect on the review network | Use high-level APIs, no IPv4 literals |
| Missing demo account | Reviewer cannot log in | Provide working demo credentials |
| Placeholder content | App looks incomplete | Replace with real, final content |
| Broken links or features | A non-functional element | Fix 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.
| Check | Action | Done? |
|---|---|---|
| Crash log | Symbolicate it with the matching dSYM | [ ] |
| Reproduce | Test on a real device, not only the simulator | [ ] |
| IPv6 | Test on an IPv6 or NAT64 network | [ ] |
| Demo account | Add stable, working credentials in App Review Information | [ ] |
| Completeness | Remove 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.



