Guides
Account validation and doctor
Prove iCloud IMAP and SMTP compatibility safely, understand account health, diagnose failures by stage, and inspect stored results without sending mail.
What account validation proves
After adding an account, run a live test before expecting later mail workflows to work:
icloud account test Personal
The test resolves the selected credential and validates both Apple mail protocols:
- IMAP connects with direct TLS, reads capabilities, authenticates, lists mailboxes, reads
INBOXstatus, and logs out; - SMTP connects, requires STARTTLS, authenticates, sends
NOOP, and quits.
The SMTP test never issues MAIL, RCPT, or DATA. The IMAP test does not append, move, copy, delete, flag, or expunge anything. It proves authentication and read-only compatibility, not message delivery.
Successful compact output has this shape:
account-test acct_… status=connected imap=ok smtp=ok imap_username=owner mailboxes=6 inbox_messages=42 inbox_unseen=3 checked_at=2026-08-06T03:00:00Z
account-tests count=1 healthy=1
An account becomes connected only when both protocol checks succeed.
Username fallback
iCloud accounts may authenticate to IMAP with either the full email address or its short local part. The CLI tries the configured username first, then the other documented forms only after an authentication rejection. It does not retry a TLS, DNS, connection, or timeout failure under a different username.
When a fallback succeeds, that exact username is persisted for later operations. The SMTP username remains the full account email address.
Validate the selected account or all accounts
With no selector, account test uses the configured default, then a sole account:
icloud account test
icloud --account Personal account test
icloud account test owner@icloud.com
Validate every configured profile with a bounded operation:
icloud account test --all
--all cannot be combined with a positional selector or global --account. The operation is limited to 100 accounts; select one account explicitly for larger inventories.
Use --verbose only when capability names are needed:
icloud account test --verbose
Normal compact output omits capability lists. JSON remains explicit:
icloud --request-id validation-01 account test --json
Stored health state
Every test records a bounded redacted health summary:
- current status:
connectedordegraded; - successful IMAP username;
- sanitized IMAP and SMTP capabilities;
- last tested time;
- last healthy time;
- the stage code for the latest failure.
A failed later test does not erase the previous last-healthy time or last-known capabilities for the protocol that could not be checked. Credential replacement or deletion returns the account to pending_validation and clears stale validation evidence.
Diagnose without contacting Apple
Run local diagnostics:
icloud doctor
icloud doctor Personal
doctor reads stored account, credential, and health metadata only. It does not resolve a credential or make a network connection unless --live is supplied.
Example local output:
doctor acct_… status=connected credential=env last_tested=2026-08-06T03:00:00Z last_healthy=2026-08-06T03:00:00Z
doctor accounts=1 status=healthy
For a new empty state:
doctor status=configuration_required
Run the same read-only protocol validation and include its result in diagnostics:
icloud doctor Personal --live
icloud doctor --all --live --json
Failure stages and exits
Failures identify the stage without exposing a credential, stored environment name, file path, raw server response, or provider capability text. Common stages include:
| Stage | Meaning | Typical exit |
|---|---|---|
credential |
The credential reference is absent, unreadable, or unresolved. | 3 or 4 |
dns |
The server hostname could not be resolved. | 5 |
connect |
A TCP connection could not be established. | 5 |
tls |
Direct IMAP TLS negotiation or certificate validation failed. | 5 |
imap_auth |
IMAP rejected every eligible username form. | 4 |
imap_list / imap_status |
Authenticated read-only compatibility failed. | 5 |
smtp_starttls |
SMTP did not offer or complete required STARTTLS. | 5 |
smtp_auth |
SMTP rejected the app-specific password. | 4 |
timeout |
The command or a protocol stage exceeded its deadline. | 5 |
Plain errors remain one compact stderr line:
error code=authentication message="account validation failed at smtp_auth"
With --json, the error envelope includes redacted structured reports and the stage so automation can choose a next action.
Timeouts and cancellation
The global timeout bounds connection establishment and every established protocol stage:
icloud --timeout 15s account test Personal
Cancellation interrupts a stalled greeting, TLS handshake, command response, or authentication exchange. A timeout never changes an authentication error into success and never triggers a send.
Live integration testing for contributors
The deterministic test suite uses local TLS IMAP and STARTTLS SMTP servers. An additional live harness is opt-in and must use a disposable iCloud account:
ICLOUD_LIVE_TEST=1 \
ICLOUD_LIVE_TEST_EMAIL=disposable@icloud.com \
ICLOUD_LIVE_TEST_PASSWORD="$DISPOSABLE_APP_PASSWORD" \
go test -run TestLiveICloudCompatibility ./internal/transport/icloud
ICLOUD_LIVE_TEST_IMAP_USERNAME is optional. The harness skips cleanly when the explicit opt-in or required values are absent. Never use a primary Apple Account password or commit the environment values, protocol output, or generated local state.
Continue with Troubleshooting for stage-specific next actions, or Output and automation for JSON and exit contracts.