infiniflow/ragflow · error · RuntimeError
Failed to fetch mailboxes; {status=}
Error message
Failed to fetch mailboxes; {status=} What it means
Raised by _fetch_all_mailboxes_for_email_account when mail_client.list returns a status other than 'OK'. Unlike the empty-result case, the server explicitly reported failure for the LIST command. This usually indicates a session-level problem (dropped connection, unselected state, server-side refusal) rather than missing folders.
Source
Thrown at common/data_source/imap_connector.py:386
if not (start_dt < msg_dt <= end_dt):
continue
slim_doc_batch.append(SlimDocument(id=email_headers.id))
for att in extract_attachments(email_msg):
slim_doc_batch.append(SlimDocument(id=_attachment_document_id(email_headers.id, att)))
if len(slim_doc_batch) >= _PAGE_SIZE:
yield slim_doc_batch
slim_doc_batch = []
if slim_doc_batch:
yield slim_doc_batch
def _fetch_all_mailboxes_for_email_account(mail_client: imaplib.IMAP4_SSL) -> list[str]:
status, mailboxes_data = mail_client.list('""', "*")
if status != _IMAP_OKAY_STATUS:
raise RuntimeError(f"Failed to fetch mailboxes; {status=}")
mailboxes = []
for mailboxes_raw in mailboxes_data:
if isinstance(mailboxes_raw, bytes):
mailboxes_str = mailboxes_raw.decode()
elif isinstance(mailboxes_raw, str):
mailboxes_str = mailboxes_raw
else:
logging.warning(f"Expected the mailbox data to be of type str, instead got {type(mailboxes_raw)=} {mailboxes_raw}; skipping")
continue
# The mailbox LIST response output can be found here:
# https://www.rfc-editor.org/rfc/rfc3501.html#section-7.2.2
#
# The general format is:
# `(<name-attributes>) <hierarchy-delimiter> <mailbox-name>`
#View on GitHub (pinned to 554fb1133a)
Solutions
- Retry the operation - build a fresh mail client via _get_mail_client() and re-run the checkpoint load.
- If persistent, reproduce with a manual LIST (e.g. via Python imaplib) to see the server's exact response and status text.
- Check server logs / ACLs if LIST is being denied for this authenticated user.
- For long jobs, reduce idle time between login and first command or implement reconnect logic upstream.
Example fix
# before
mailboxes = _fetch_all_mailboxes_for_email_account(client) # RuntimeError: status='NO'
# after
for attempt in range(3):
try:
mailboxes = _fetch_all_mailboxes_for_email_account(client)
break
except RuntimeError:
client = connector._get_mail_client() # fresh session
else:
raise Defensive patterns
Strategy: retry
Try / catch
for attempt in range(3):
try:
mailboxes = _fetch_all_mailboxes_for_email_account(client)
break
except RuntimeError as e:
if 'Failed to fetch mailboxes' not in str(e) or attempt == 2:
raise
time.sleep(2 ** attempt)
client = connector._get_mail_client() # fresh authenticated session Prevention
- Always re-login (fresh IMAP4_SSL session) before retrying after a non-OK status.
- Keep long sync jobs active or reconnect on a schedule to avoid idle disconnects.
- Log the raw status string; IMAP statuses ('NO', 'BYE') distinguish server refusal from disconnect.
When it happens
Trigger: The IMAP session timed out or was closed between login and LIST; the server rejects LIST with 'NO' due to ACL or namespace restrictions; a transient server failure mid-sync. Raised as a RuntimeError with the raw status string embedded.
Common situations: Long-running sync jobs where the connection idles out; load-shedding or maintenance windows on the mail server; aggressive per-command rate limiting; proxies or middleboxes between client and server.
Related errors
- Failed to fetch email ids; {status=}
- Failed to log into imap server; {status=}
- Credential item {name=} was not found
- Credential item {name=} must be of type str, instead receive
- Failed to find any mailboxes for this email account
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/5c912d8e27190324.
Report an issue: GitHub.