commaai/openpilot · error · LPAError
profile {iccid} not found
Error message
profile {iccid} not found What it means
After sending the SetNickname request, the eUICC's response status tag is parsed: code 0x01 per PROFILE_ERROR_CODES means iccidOrAidNotFound. The library raises LPAError (specifically the base LPA error, cf. LPAProfileNotFoundError in the base module) so callers can distinguish 'unknown profile' from transport failures.
Source
Thrown at openpilot/common/esim/lpa.py:407
list_ok = find_tag(root, TAG_OK)
if list_ok is None:
return []
return [decode_struct(value, PROFILE) for tag, value in iter_tlv(list_ok) if tag == 0xE3]
def list_profiles(client: AtClient) -> list[dict]:
return decode_profiles(es10x_command(client, TAG_PROFILE_INFO_LIST.to_bytes(2, "big") + b"\x00"))
def set_profile_nickname(client: AtClient, iccid: str, nickname: str) -> None:
nickname_bytes = nickname.encode("utf-8")
if len(nickname_bytes) > 64:
raise ValueError("Profile nickname must be 64 bytes or less")
content = encode_tlv(TAG_ICCID, string_to_tbcd(iccid)) + encode_tlv(0x90, nickname_bytes)
response = es10x_command(client, encode_tlv(TAG_SET_NICKNAME, content))
code = require_tag(require_tag(response, TAG_SET_NICKNAME, "SetNicknameResponse"), TAG_STATUS, "SetNickname status")[0]
if code == 0x01:
raise LPAError(f"profile {iccid} not found")
if code != 0x00:
raise RuntimeError(f"SetNickname failed with status 0x{code:02X}")
# --- ES9P HTTP ---
def es9p_request(smdp_address: str, endpoint: str, payload: dict, error_prefix: str = "Request", session: requests.Session | None = None) -> dict:
url = f"https://{smdp_address}/gsma/rsp2/es9plus/{endpoint}"
headers = {"User-Agent": "gsma-rsp-lpad", "X-Admin-Protocol": "gsma/rsp/v2.3.0", "Content-Type": "application/json"}
http = session or requests
resp = http.post(url, json=payload, headers=headers, timeout=HTTP_TIMEOUT, verify=GSMA_CI_BUNDLE)
resp.raise_for_status()
if not resp.content:
return {}
data = resp.json()
if "header" in data and "functionExecutionStatus" in data["header"]:
status = data["header"]["functionExecutionStatus"]
if status.get("status") == "Failed":View on GitHub (pinned to 516ec1e682)
Solutions
- Call list_profiles(client) and use an ICCID from the fresh list
- Catch LPAError/LPAProfileNotFoundError specifically to show 'profile not found' rather than a generic failure
- Validate the ICCID format (19-20 digits, Luhn) before sending
Example fix
# before
set_profile_nickname(client, stale_iccid, 'car') # LPAError: profile ... not found
# after
from openpilot.common.esim.lpa import list_profiles, set_profile_nickname
live = {p['iccid'] for p in list_profiles(client)}
if stale_iccid not in live:
raise SystemExit(f'{stale_iccid} no longer on eUICC; profiles: {sorted(live)}')
set_profile_nickname(client, stale_iccid, 'car') Defensive patterns
Strategy: validation
Validate before calling
from openpilot.common.esim.lpa import list_profiles
live_iccids = {p['iccid'] for p in list_profiles(client)}
if iccid not in live_iccids:
raise SystemExit(f'{iccid} not on eUICC; available: {sorted(live_iccids)}') Type guard
def iccid_exists(client, iccid: str) -> bool: return any(p['iccid'] == iccid for p in list_profiles(client))
Try / catch
from openpilot.common.esim.base import LPAError
try:
set_profile_nickname(client, iccid, name)
except LPAError as e:
if 'not found' in str(e):
# refresh and retry once with a live iccid
...
raise Prevention
- Never cache ICCIDs across user interactions; re-list before operating
- Catch LPAError separately from transport errors to give accurate user feedback
- Validate ICCID length/Luhn before sending to the eUICC
When it happens
Trigger: set_profile_nickname() with an ICCID that does not exist on the eUICC: stale ICCID captured before a delete, typo'd digit, or an ICCID for a different device's eUICC.
Common situations: UI holds a cached profile list that is out of date; profile was deleted by another flow; ICCID transcribed with a missing/extra digit (the TBCD encoding also changes if an odd digit count is mishandled).
Related errors
- Missing {label or f'tag 0x{target:X}'}
- APDU failed with SW={sw1:02X}{sw2:02X}
- Profile nickname must be 64 bytes or less
- SetNickname failed with status 0x{code:02X}
- AuthenticateServer rejected by eUICC: {AUTH_SERVER_ERROR_COD
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/9f3623efe6300a95.
Report an issue: GitHub.