commaai/openpilot · error · RuntimeError
Missing +CGLA response
Error message
Missing +CGLA response
What it means
send_apdu() sends an AT+CGLA command and scans the response lines for one starting with '+CGLA:'. If the modem replies only with 'Ok' (or unrelated lines) and no +CGLA payload line, the response cannot be parsed into (data, sw1, sw2) and RuntimeError('Missing +CGLA response') is raised.
Source
Thrown at openpilot/common/esim/lpa.py:252
time.sleep(OPEN_ISDR_RETRY_DELAY_S)
if attempt == OPEN_ISDR_RESET_ATTEMPT:
self._reset_modem()
raise RuntimeError("Failed to open ISD-R after retries")
def send_apdu(self, apdu: bytes) -> tuple[bytes, int, int]:
for attempt in range(SEND_APDU_RETRIES):
try:
if not self.channel:
self.open_isdr()
hex_payload = apdu.hex().upper()
for line in self.query(f'AT+CGLA={self.channel},{len(hex_payload)},"{hex_payload}"'):
if line.startswith("+CGLA:"):
parts = line.split(":", 1)[1].split(",", 1)
if len(parts) == 2:
data = bytes.fromhex(parts[1].strip().strip('"'))
if len(data) >= 2:
return data[:-2], data[-2], data[-1]
raise RuntimeError("Missing +CGLA response")
except (RuntimeError, ValueError):
self.channel = None
if attempt == SEND_APDU_RETRIES - 1:
raise
raise RuntimeError("send_apdu failed")
# --- TLV utilities ---
def iter_tlv(data: bytes, with_positions: bool = False) -> Generator:
idx, length = 0, len(data)
while idx < length:
start_pos = idx
tag = data[idx]
idx += 1
if tag & 0x1F == 0x1F: # Multi-byte tag
tag_value = tag
while idx < length:View on GitHub (pinned to 516ec1e682)
Solutions
- Let the built-in retry run — it already clears self.channel and reopens the ISD-R; if the error still surfaces, the channel loss is persistent
- Reset the modem (lte.sh restart / _reset_modem) and retry the whole eSIM operation from the start
- Ensure exclusive access to the AT port (hold /dev/shm/modem.lock) so nothing else reads responses
- Update modem firmware if +CGLA omissions are reproducible with healthy channels
Example fix
# before client.send_apdu(apdu) # RuntimeError: Missing +CGLA response (after 3 retries) # after — hard reset modem, rebuild client, retry once client.close() client._reset_modem() client = AtClient() client.send_apdu(apdu)
Defensive patterns
Strategy: retry
Try / catch
from openpilot.common.esim.lpa import AtClient
try:
data, sw1, sw2 = client.send_apdu(apdu)
except RuntimeError as e:
if 'Missing +CGLA response' in str(e):
client.close()
client._reset_modem()
client = AtClient()
data, sw1, sw2 = client.send_apdu(apdu)
else:
raise Prevention
- Rely on send_apdu's internal retry; treat surfacing of this error as 'channel persistently broken'
- Serialize eSIM operations behind the modem lock to prevent interleaved reads
- Keep modem firmware current — +CGLA omissions are firmware bugs
When it happens
Trigger: Modem acknowledges the command but omits the +CGLA data line — firmware quirk after channel state corruption, channel silently closed by modem, or a race where a previous response was consumed by another reader. Raised inside send_apdu's retry loop: channel is reset and the APDU retried up to SEND_APDU_RETRIES=3 times before surfacing.
Common situations: Modem dropped the logical channel between operations (modem internal reset); interleaved serial access by another process swallowing the +CGLA line; modem firmware that occasionally returns bare Ok for CGLA when the channel is invalid.
Related errors
- AT command failed: {line}
- Failed to open ISD-R after retries
- AT command timed out
- no eUICC detected
- send_apdu failed
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/98b25f1d17bf75ad.
Report an issue: GitHub.