commaai/openpilot · error · LPAError
EnableProfile failed: {PROFILE_ERROR_CODES.get(code, 'unknow
Error message
EnableProfile failed: {PROFILE_ERROR_CODES.get(code, 'unknown')} (0x{code:02X}) What it means
switch_profile() enables a profile via EnableProfile; after one retry following a CAT-busy reset, any status code besides PROFILE_OK or PROFILE_NOT_IN_DISABLED_STATE raises LPAError with the status name and hex code.
Source
Thrown at openpilot/common/esim/lpa.py:774
def nickname_profile(self, iccid: str, nickname: str) -> None:
with self._acquire_channel():
set_profile_nickname(self._client, iccid, nickname)
def _enable_profile(self, iccid: str) -> int:
inner = encode_tlv(TAG_OK, encode_tlv(TAG_ICCID, string_to_tbcd(iccid)))
inner += b'\x01\x01\x01' # refreshFlag=1
response = es10x_command(self._client, encode_tlv(TAG_ENABLE_PROFILE, inner))
return require_tag(require_tag(response, TAG_ENABLE_PROFILE, "EnableProfileResponse"), TAG_STATUS, "EnableProfile status")[0]
def switch_profile(self, iccid: str) -> None:
with self._acquire_channel():
code = self._enable_profile(iccid)
if code == PROFILE_CAT_BUSY: # stale eUICC transaction, reset and retry
self._client._reset_modem()
self._client.open_isdr()
code = self._enable_profile(iccid)
if code not in (PROFILE_OK, PROFILE_NOT_IN_DISABLED_STATE):
raise LPAError(f"EnableProfile failed: {PROFILE_ERROR_CODES.get(code, 'unknown')} (0x{code:02X})")
def is_euicc(self) -> bool:
# +CCHO:<n> -> ISD-R applet present, eUICC. Any error -> non-eUICC.
with self._acquire_lock():
try:
lines = self._client.query(f'AT+CCHO="{ISDR_AID}"')
except RuntimeError:
return False
for line in lines:
if line.startswith("+CCHO:") and (ch := line.split(":", 1)[1].strip()):
try:
self._client.query(f"AT+CCHC={ch}")
except (RuntimeError, TimeoutError):
pass
self._client.channel = None
return True
return False
View on GitHub (pinned to 516ec1e682)
Solutions
- Verify the ICCID exists via list_profiles() before switching
- Retry after a full modem reset / power cycle to clear stuck eUICC state
- Update AGNOS/modem firmware if the eUICC repeatedly returns unknown status codes
Defensive patterns
Strategy: retry
Validate before calling
assert any(p.iccid == iccid for p in lpa.list_profiles()), "unknown ICCID"
Try / catch
try:
lpa.switch_profile(iccid)
except LPAError as e:
if "EnableProfile failed" in str(e):
lpa._client._reset_modem()
lpa.switch_profile(iccid) Prevention
- Validate the ICCID exists before switching
- Reset the modem to clear stuck eUICC transactions before retrying
When it happens
Trigger: switch_profile(iccid) where the ICCID is unknown, the target profile is already enabled (accepted) but the eUICC returns a different error, or a concurrent CAT/modem transaction keeps it busy past the built-in reset+retry.
Common situations: Switching to a profile that was deleted; eUICC in a stuck transaction state that survives one modem reset; unsupported profile state transitions on older eUICC firmware.
Related errors
- DeleteProfile failed: {PROFILE_ERROR_CODES.get(code, 'unknow
- Profile installation failed at {cmd_name}: {err_name}
- refusing to delete a comma profile
- APDU failed with SW={sw1:02X}{sw2:02X}
- SetNickname failed with status 0x{code:02X}
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/676338eac1274065.
Report an issue: GitHub.