Learn

eSIM profile download failed: causes, error codes and how to test downloads

Why eSIM profile downloads fail, from bad activation codes and TLS errors to full eUICCs and used QR codes, plus how to diagnose and test downloads.

By SimCheck.ai team · Updated · 10 min read

When an eSIM profile download fails, the cause is almost always in one of four places: the activation code itself, the connection from the device to the SM-DP+ server, the state of the download order on that server, or the eUICC that has to install the profile. The GSMA consumer specification SGP.22 defines precise status codes for most of these failures, but phones show users only a generic message, so diagnosis means getting the underlying code. This guide walks through each failure point, how errors surface on Android, iOS and IoT modules, and how to test downloads so they fail in the lab instead of in the field.

How an eSIM download works, step by step

Every failure maps to a step in the download sequence. In the SGP.22 model, the device’s LPA (Local Profile Assistant) drives the process:

  1. Read the activation code. From a QR code, manual entry, a carrier app or a discovery service (SM-DS).
  2. Reach the SM-DP+. Resolve its address in DNS and open an HTTPS session on the ES9+ interface.
  3. Mutual authentication. The SM-DP+ and the eUICC prove their identities with GSMA-issued certificates.
  4. Match the order. The SM-DP+ looks up the download order using the Matching ID and, if the order is bound to one, checks the EID.
  5. Confirmation code (optional). If the order requires one, the device must supply it.
  6. Bind and deliver. The SM-DP+ produces a Bound Profile Package encrypted for that eUICC.
  7. Install. The eUICC decrypts and installs the profile, then sends a notification back to the SM-DP+.
  8. Enable and attach. The profile is enabled and the device registers on the network.

Steps 1 to 7 are the download. Step 8 is a separate problem. A profile that installs but gets no service is an attach or provisioning issue (an attach reject cause, a missing HLR/HSS record, a wrong APN), not a download failure.

Where eSIM downloads fail

1. Malformed or wrong activation code

SGP.22 defines the activation code as 1$<SM-DP+ address>$<Matching ID>, optionally followed by the SM-DP+ OID and a flag that says a confirmation code is required. When the code is printed as a QR it carries an LPA: prefix. The specification limits the code to 255 characters, says devices must treat any format value other than 1 as invalid, and restricts the Matching ID to uppercase letters, digits and hyphens (SGP.22 v2.2.2, section 4.1).

Typical mistakes:

  • Lowercase or extra whitespace introduced when codes are pasted from email or spreadsheets.
  • The wrong delimiter count when optional fields are left blank.
  • A test SM-DP+ address in a production QR, or the reverse.
  • An SM-DP+ address that doesn’t match the server’s configured name. The server compares it case-insensitively and rejects mismatches with 8.8.1 / 3.8, “Invalid SM-DP+ Address”.

2. Network, DNS and TLS problems

The device needs working IP connectivity before the eUICC is involved at all. A phone typically uses Wi-Fi or an existing cellular line. An IoT device uses its current profile, often a bootstrap profile. Failures here include:

  • DNS that can’t resolve the SM-DP+ FQDN (split-horizon corporate DNS, filtering resolvers, a bootstrap APN with restricted DNS).
  • Firewalls and captive portals that block or intercept HTTPS to the SM-DP+.
  • TLS validation failures. SGP.22 requires the LPA to verify the SM-DP+ TLS certificate and to abort the session if verification fails. TLS-intercepting proxies break this. So can a device clock far enough off that certificate validity checks fail, which happens on IoT hardware without a reliable real-time clock.
  • Certificate chain mismatches. The SM-DP+ must hold a certificate signed by a GSMA CI root the eUICC trusts. If it doesn’t, you see 8.8.4 / 3.7 (no suitable SM-DP+ certificate) or 8.8.2 / 3.1 (none of the proposed key identifiers supported). If the eUICC’s own chain isn’t trusted by the server, you see 8.11.1 / 3.9 (unknown CI public key).

On Android these usually appear as ERROR_CONNECTION_ERROR, ERROR_TIME_OUT or ERROR_CERTIFICATE_ERROR.

3. eUICC memory is full

Each profile takes space on the chip, and consumer devices that have collected many travel eSIMs do run out. The SM-DP+ reports 8.1 / 4.8, “eUICC does not have sufficient space for this Profile”. If the shortfall is only discovered during installation, the eUICC reports installFailedDueToInsufficientMemoryForProfile. Android surfaces this as ERROR_EUICC_INSUFFICIENT_MEMORY. From API level 35 (Android 15), apps can also check getAvailableMemoryInBytes() before starting (Android EuiccManager reference). Deleting unused profiles is the fix.

4. The profile was already used, expired or ran out of retries

This is the most common cause of “it worked yesterday” reports. The SM-DP+ tracks each profile through a lifecycle (SGP.22, section 3.1.6):

SM-DP+ state Meaning What a download attempt sees
Available In inventory, not yet ordered Not downloadable
Allocated / Linked Reserved, optionally linked to an EID Not downloadable until released
Confirmed Reserved with a Matching ID (and confirmation code if needed) Not downloadable until released
Released Network side provisioned; ready Download proceeds
Downloaded / Installed Delivered to a device Further attempts refused
Error Retry limits exceeded, user rejection or install failure Refused
Unavailable Cannot be reused Refused

The matching status codes:

  • 8.2 / 1.2. Profile not yet released. The operator hasn’t finished network provisioning.
  • 8.8.5 / 4.10. The download order has expired.
  • 8.8.5 / 6.4. The maximum number of download attempts has been exceeded. The specification has the SM-DP+ count attempts per profile and terminate the order once the limit is passed.
  • 8.2.6 / 3.8. Matching ID refused, typical for a code that has already been consumed or never existed.

A related device-side failure is installFailedDueToIccidAlreadyExistsOnEuicc. The same profile (same ICCID) is already installed on this chip, often after a retry that actually succeeded the first time.

5. Matching ID, confirmation code and EID binding

Orders can be locked down in three ways, and each has its own error:

  • Confirmation code. Missing (8.2.7 / 2.2), wrong (8.2.7 / 3.8) or too many wrong attempts (8.2.7 / 6.4), after which the order is terminated. Android reports ERROR_INVALID_CONFIRMATION_CODE.
  • EID binding. If the operator created the order for a specific EID, any other eUICC gets 8.1.1 / 3.8, “EID doesn’t match the expected value”.
  • Matching ID. A Matching ID the SM-DP+ doesn’t know is refused. The specification has the server process only requests that contain a Matching ID it already knows.

6. Eligibility, policy rules and device locks

The SM-DP+ can run an eligibility check on the device and eUICC information it receives. If no profile type fits, it returns 8.2.5 / 4.3, “No eligible Profile for this eUICC/Device”. Profile Policy Rules (PPRs) and the eUICC’s rules authorisation table can also block installation (pprNotAllowed on the eUICC, ERROR_DISALLOWED_BY_PPR on Android). On the device side, carrier-locked phones refuse other operators’ profiles (ERROR_CARRIER_LOCKED), and some LPAs reject profiles from carriers they don’t support (ERROR_INCOMPATIBLE_CARRIER).

7. Server-side and installation errors

Some failures are nobody’s configuration mistake: an SM-DP+ outage or HTTP 5xx, a session interrupted mid-transfer (installFailedDueToInterruption), or a profile package the eUICC can’t process (installFailedDueToPEProcessingError, which also covers unsupported profile versions). Android groups many of these under ERROR_INSTALL_PROFILE or ERROR_INVALID_RESPONSE. Retrying is reasonable for transient transport errors. Retrying a processing error without changing the profile usually isn’t.

Quick reference: common SGP.22 status codes

Status codes are written as subject code / reason code. These come from the ES9+ function tables in SGP.22 v2.2.2, section 5.6.

Subject / reason Meaning Usual fix
8.8.1 / 3.8 Invalid SM-DP+ address Correct the address in the activation code
8.8.4 / 3.7 No SM-DP+ certificate for the eUICC’s CI Provider must deploy a matching certificate
8.1 / 4.8 Insufficient eUICC memory Delete unused profiles
8.1.1 / 3.8 EID does not match the order Re-issue the order for the right EID
8.2 / 1.2 Profile not released Operator completes provisioning
8.2.5 / 4.3 No eligible profile for this device Check device compatibility or profile type
8.2.6 / 3.8 Matching ID refused Code consumed, mistyped or never created
8.2.7 / 3.8 or 6.4 Confirmation code wrong or retries exhausted Re-enter code or request a new order
8.8.5 / 4.10 Download order expired Request a new order
8.8.5 / 6.4 Download attempts exceeded Provider resets or replaces the order

How errors surface by platform

Android

Apps using the EuiccManager API get one of three result codes: EMBEDDED_SUBSCRIPTION_RESULT_OK, EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR (the user must act, for example by granting consent or entering a confirmation code) or EMBEDDED_SUBSCRIPTION_RESULT_ERROR. Since API level 30, the callback also carries EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE (which stage failed: download, HTTP, SM-DX, eUICC and so on), EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE (the ERROR_* constants above) and, when the failure came from the server, the SGP.22 subject and reason codes in EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE and ..._SMDX_REASON_CODE. Google’s eSIM error handling guide describes how these are packed. End users see none of this, so carrier apps should log it.

iOS

iOS exposes much less. The carrier-entitled addPlan API in Core Telephony returns only success, fail, cancel or unknown (Apple developer documentation). Users see messages such as “Unable to Complete Cellular Plan Change” without a code. Apple’s own troubleshooting article suggests toggling Airplane Mode, restarting and checking for a carrier settings update, then contacting the carrier with the error message. In practice, iOS failures are diagnosed from the SM-DP+ side. SGP.22 lets the SM-DP+ report download progress to the operator (ES2+.HandleDownloadProgressInfo), including which step was reached and the result.

IoT modules and SGP.32 devices

Modules have no screen and often no built-in LPA. Under SGP.22-style setups, a host-side LPA talks to the eUICC through logical-channel AT commands (AT+CCHO / AT+CGLA from 3GPP TS 27.007) and logs the raw status codes itself. Under SGP.32, an eIM instructs the device’s IPA to download, and the IPA reports the outcome back to the eIM. The SM-DP+ status codes are the same, but you read them from eIM and device logs. See how to test SGP.32 devices for the IoT-specific flow.

A diagnosis routine that works

  1. Get the real code. The SM-DP+ subject/reason code, the Android error and operation codes, or the eIM result. Don’t debug from “download failed”.
  2. Validate the activation code. Check the format, uppercase Matching ID, the SM-DP+ address and the delimiter count.
  3. Check the order state with the provider: released, expired, consumed, retry count, EID binding, confirmation code required.
  4. Check the path to the SM-DP+. DNS resolution, HTTPS reachability from the same network the device uses, no TLS interception, correct device time.
  5. Check the eUICC. Free memory, an existing profile with the same ICCID, and policy rules.
  6. Check the device. Carrier lock, LPA or OS version, eSIM support for that profile type.
  7. Only then retry, ideally with a fresh order so a consumed or exhausted order doesn’t mask a fixed root cause.

How to test eSIM downloads systematically

Download problems are cheap to find before launch and expensive after it. A useful test plan covers the happy path and the failure paths deliberately:

Scenario How to set it up Expected result
First download, QR Fresh order, released profile Installs, enables, attaches
Reuse a single-use code Repeat the same activation code Refused (8.2.6 / 3.8 or similar), clear user message
Expired order Let the order’s time to live lapse 8.8.5 / 4.10
Wrong confirmation code Enter a bad code repeatedly 8.2.7 / 3.8, then 6.4 and order terminated
EID-bound order on the wrong device Bind to EID A, download on EID B 8.1.1 / 3.8
Full eUICC Fill the chip with test profiles 8.1 / 4.8 or install-time memory error
Delete and re-download Install, delete, retry the same code Matches the provider’s re-download policy
Restricted network Block DNS or HTTPS to the SM-DP+ Connection or timeout error, no partial state
IoT bootstrap path Download over the bootstrap profile’s APN Profile installs; fallback behaves as designed

Treat download counters as test data. Single-use profiles should fail predictably on the second attempt. Profiles with a fixed download allowance should fail after the count is reached, and “unlimited” profiles should survive repeated install/delete cycles without exhausting an order. GSMA’s TS.48 generic test profile covers device testing on test networks. Download behavior against production SM-DP+ servers and live networks needs real profiles.

In SimCheck.ai, each profile in the eSIM inventory carries its download limit (Unlimited, Single Use or a fixed count with a running counter), its status, and which site and modem it’s installed on. Each modem installs profiles either through SGP.32 via a cloud eIM or through an SGP.22-style LPA, so the same profile can be exercised on both paths. Every run keeps its logs, decoded signaling and packet captures, so a failed download shows the step and the code instead of a generic error.

Test downloads on real modems

Testing the download path on real modems with your own profiles is the most reliable way to catch expired orders, exhausted counters and eligibility mismatches before customers do. See how eSIM testing on SimCheck.ai covers download, attach, data, SMS and voice end to end, or use the eSIM testing checklist to plan your own coverage.

Frequently asked questions

Can I reuse an eSIM QR code after deleting the profile?

Usually not. Most activation codes point to a single download order on the SM-DP+. Once the profile has been downloaded and installed, the order is consumed, and a second attempt is refused even if the profile was deleted from the device. Some providers configure reusable or re-downloadable profiles, but that is a server-side policy, not something the device can override. Ask the provider to release a new profile or re-arm the existing order.

What does SGP.22 error 8.8.5 mean?

Subject code 8.8.5 refers to the SM-DP+ download order. Combined with reason code 4.10 it means the order has expired (time to live exceeded). Combined with reason code 6.4 it means the maximum number of download attempts for that order has been exceeded. In both cases the fix is on the provider side, usually a new or reset download order.

How do I see the detailed error code on Android?

Apps using the EuiccManager API receive a result code (OK, resolvable error or error) and, on Android 11 and later, extras with an operation code, an error code and, where the failure came from the server, the GSMA SGP.22 subject and reason codes. End users only see a generic message, so detailed codes normally come from the carrier app, the LPA logs or the SM-DP+ side.

Why does the same QR code work on one phone but not another?

Common reasons are that the download order is bound to a specific EID, that the second device is carrier locked, that the profile type is not eligible for that device, or that the first successful download already consumed the order. Compare the EID the provider expects with the EID shown on the device.

Do IoT devices without a screen get the same errors?

Yes. The SM-DP+ returns the same status codes whether the request comes from a phone LPA or an IoT device. On SGP.32 devices the IoT Profile Assistant performs the download on behalf of the eIM and reports the result back to it, so the error appears in the eIM or device logs rather than on a screen.

See it on your own eSIMs

Start a free trial with test tokens included, or book a demo to test your profiles across your target markets.