How to Connect to an IMAP Server: Hosts, Ports, SSL/TLS & OAuth (2026 Guide)

Definition

What an IMAP server connection actually is

An IMAP server connection is a persistent TCP session between an email client and a mail server that uses the Internet Message Access Protocol (IMAP) to synchronize, retrieve, and manage email messages stored remotely - without downloading or deleting them from the server.

Unlike POP3, which was designed to download messages locally and optionally delete them from the server, IMAP was built for synchronization. Every read, flag, move, or deletion you perform locally is reflected on the server - and therefore across every device connected to the same mailbox. This is why IMAP became the de facto protocol for modern email clients.

At the network level, an IMAP server connection opens a TCP socket to a mail server (typically port 993 for SSL/TLS or port 143 for STARTTLS), performs a TLS handshake, authenticates the user (via password, app password, or OAuth 2.0 XOAUTH2), then enters a state machine: Not Authenticated, Authenticated, Selected (inside a mailbox folder), or Logout. Most of the useful commands - FETCH, SEARCH, STORE, COPY, EXPUNGE - only work in the Selected state.

For developers building email integrations, an IMAP server connection is the lowest-level building block. You establish it, authenticate it, SELECT a mailbox, then poll or IDLE for new messages. This guide covers every step: the right host and port for each provider, the correct authentication method in 2026 (OAuth is increasingly mandatory), and a complete troubleshooting reference for the most common failure modes.

Technical Reference

IMAP ports explained: 143, 993, and when STARTTLS is OK

There are exactly two IMAP ports in active use: 993 (Implicit TLS, the modern standard) and 143 (STARTTLS upgrade or plain-text, which most servers no longer allow plain). Knowing the difference matters because using the wrong port is one of the most common causes of connection failures when building an IMAP integration.

Legacy / Conditional
143
IMAP with STARTTLS upgrade

The client connects in plain-text, then issues a STARTTLS command to upgrade to TLS. Most modern servers require this upgrade and reject plain-text sessions entirely.

Acceptable on corporate IMAP servers and self-hosted mail (e.g., Dovecot, Postfix)
More complex handshake: your client must handle the STARTTLS flow explicitly
Avoid for cloud providers - they all prefer 993
Port 143 without STARTTLS is blocked by virtually every modern mail server

2026 recommendation: always use port 993 with SSL_CONTEXT (implicit TLS). If you are building against a corporate IMAP server that only exposes port 143, enable STARTTLS and verify the server certificate. Never connect to an IMAP server over plain-text in production - credentials travel in the clear and most providers now refuse such connections outright.

A quick note on RFC 9051 (IMAP4rev2), published in August 2021 as the successor to RFC 3501. IMAP4rev2 formally requires TLS for any connection carrying credentials, deprecates MD5-based authentication mechanisms, and removes the LIST-EXTENDED incompatibilities that caused subtle bugs in older clients. Most major cloud providers (Gmail, Outlook) have been IMAP4rev2-compatible in practice for years, even before the RFC was finalized. For practical purposes, target port 993 + TLS and you will be RFC 9051 compliant by default.

Unipile - IMAP Host & Port Table
Reference Table

Host and port settings table - Gmail, Outlook, Yahoo, iCloud, Zoho, Fastmail, AOL, ProtonMail Bridge

The table below lists the correct IMAP server connection settings for the most widely used email providers. All values have been verified against each provider's official documentation as of May 2026. Use this as your quick-reference when configuring an IMAP client or building an IMAP API integration.

Provider IMAP Host Port Encryption OAuth 2.0 (XOAUTH2) Notes
Gmail logoGmail
imap.gmail.com 993 SSL/TLS
Yes (required for new apps)
App passwords work but OAuth is strongly preferred. Enable IMAP in Gmail settings first.
Outlook logoOutlook / Microsoft 365
outlook.office365.com 993 SSL/TLS
Yes (Basic Auth deprecated Dec 2026)
Basic Auth end-of-life December 2026 for all tenants. Migrate to OAuth now.
Y!Yahoo Mail
imap.mail.yahoo.com 993 SSL/TLS
Yes
App password required if 2FA is enabled. OAuth via Yahoo's developer portal.
iCiCloud Mail
imap.mail.me.com 993 SSL/TLS
No (app-specific password only)
Apple requires an app-specific password from appleid.apple.com. No OAuth XOAUTH2 support.
ZoZoho Mail
imap.zoho.com 993 SSL/TLS
Yes
OAuth via Zoho Accounts API. IMAP must be enabled per mailbox in Zoho Mail settings.
FmFastmail
imap.fastmail.com 993 SSL/TLS
Yes (JMAP preferred)
Fastmail natively supports JMAP (faster than IMAP) but IMAP is fully supported. App passwords available.
AOLAOL Mail
imap.aol.com 993 SSL/TLS
Yes
Now part of Yahoo Inc. App password required if 2FA enabled. OAuth via Yahoo's developer portal.
PrProtonMail Bridge
127.0.0.1 1143 STARTTLS
No (Bridge token auth)
ProtonMail Bridge runs locally and exposes a local IMAP server. Not suitable for server-side integrations.
GGeneric IMAP
your-mail-server.com 993 / 143 SSL/TLS STARTTLS
Varies (check server config)
Dovecot, Postfix, Zimbra, Courier. Check your server's CAPABILITY response for supported auth mechanisms.
Gmail logo Gmail
IMAP Host imap.gmail.com
Port 993
Encryption SSL/TLS
OAuth 2.0
Yes (required for new apps)
App passwords work but OAuth is strongly preferred. Enable IMAP in Gmail settings first.
Outlook logo Outlook / Microsoft 365
IMAP Host outlook.office365.com
Port 993
Encryption SSL/TLS
OAuth 2.0
Yes (Basic Auth deprecated Dec 2026)
Basic Auth end-of-life December 2026 for all tenants. Migrate to OAuth now.
Y! Yahoo Mail
IMAP Host imap.mail.yahoo.com
Port 993
Encryption SSL/TLS
OAuth 2.0
Yes
App password required if 2FA is enabled. OAuth via Yahoo's developer portal.
iC iCloud Mail
IMAP Host imap.mail.me.com
Port 993
Encryption SSL/TLS
OAuth 2.0
No (app-specific password only)
Apple requires an app-specific password from appleid.apple.com. No OAuth XOAUTH2 support.
Zo Zoho Mail
IMAP Host imap.zoho.com
Port 993
Encryption SSL/TLS
OAuth 2.0
Yes
OAuth via Zoho Accounts API. IMAP must be enabled per mailbox in Zoho Mail settings.
Fm Fastmail
IMAP Host imap.fastmail.com
Port 993
Encryption SSL/TLS
OAuth 2.0
Yes (JMAP preferred)
Fastmail natively supports JMAP (faster than IMAP) but IMAP is fully supported. App passwords available.
AOL AOL Mail
IMAP Host imap.aol.com
Port 993
Encryption SSL/TLS
OAuth 2.0
Yes
Now part of Yahoo Inc. App password required if 2FA enabled. OAuth via Yahoo's developer portal.
Pr ProtonMail Bridge
IMAP Host 127.0.0.1
Port 1143
Encryption STARTTLS
OAuth 2.0
No (Bridge token auth)
ProtonMail Bridge runs locally and exposes a local IMAP server. Not suitable for server-side integrations.
G Generic IMAP
IMAP Host your-mail-server.com
Port 993 / 143
Encryption SSL/TLS STARTTLS
OAuth 2.0
Varies (check server config)
Dovecot, Postfix, Zimbra, Courier. Check your server's CAPABILITY response for supported auth mechanisms.

Note on ProtonMail: the Bridge architecture means ProtonMail IMAP connections are only viable for single-user desktop setups. For multi-account or server-side integrations, ProtonMail is effectively unsupported via standard IMAP. For Gmail and Outlook at scale, see our dedicated guides on OAuth for email APIs and Microsoft Graph API Email.

Code Example

Step-by-step: opening a raw IMAP server connection

Below are minimal, working examples of how to open an authenticated IMAP server connection using Python's built-in imaplib and Node.js with imapflow. Both examples connect to Gmail on port 993 using app-password authentication. For OAuth XOAUTH2 see H2 #7 below.

Python (imaplib)
Node.js (imapflow)
imap_connect.py
import imaplib import ssl # IMAP server settings IMAP_HOST = "imap.gmail.com" IMAP_PORT = 993 USERNAME = "you@gmail.com" PASSWORD = "your-app-password" # app password, not your account password # Create SSL context (verify certificates) context = ssl.create_default_context() # Open SSL connection on port 993 with imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT, ssl_context=context) as imap: # Authenticate imap.login(USERNAME, PASSWORD) # Select inbox (returns message count) status, data = imap.select("INBOX") print(f"Inbox has {data[0].decode()} messages") # Search for unseen messages status, msg_ids = imap.search(None, "UNSEEN") print(f"Unseen: {msg_ids[0].decode()}") # Logout (connection closes at end of 'with' block)
imap_connect.mjs
// npm install imapflow import { ImapFlow } from 'imapflow'; const client = new ImapFlow({ host: 'imap.gmail.com', port: 993, secure: true, // SSL/TLS on port 993 auth: { user: 'you@gmail.com', pass: 'your-app-password' }, logger: false }); await client.connect(); // Lock the INBOX mailbox for exclusive access let lock = await client.getMailboxLock('INBOX'); try { // Fetch last 5 messages (headers only) for await (let msg of client.fetch('1:5', { envelope: true })) { console.log(msg.envelope.subject); } } finally { lock.release(); } await client.logout();

The Python example uses IMAP4_SSL - the higher-level SSL wrapper that handles the TLS handshake automatically. Avoid using IMAP4 + manual starttls() for cloud providers as it adds complexity without benefit. For Node.js, imapflow is the modern, Promise-based choice (the older node-imap library is unmaintained as of 2024 and does not support XOAUTH2).

Both examples use app passwords, which are the simplest credential type for quick testing. For production systems handling multiple users, you will need OAuth 2.0 - see the XOAUTH2 section below. For a complete production-ready solution without managing raw IMAP connections, see the IMAP API developer guide.

Skip the IMAP boilerplate. Unipile gives you read, send, and sync across Gmail, Outlook, and IMAP in a single REST API - no connection management required.

Skip IMAP boilerplate - Build it with Unipile
Authentication

Authentication: password, app password, and OAuth 2.0 (XOAUTH2)

An IMAP server connection requires you to authenticate after the TLS handshake. There are three authentication methods in use today - each with a different security profile, complexity level, and compatibility with cloud providers in 2026.

1
Basic Authentication (username + password)

The original IMAP AUTH PLAIN / LOGIN mechanism. You send the account email address and account password directly to the IMAP server. Simple to implement but increasingly blocked by cloud providers on security grounds.

Deprecated for cloud
2
App Password

A 16-character token generated by the provider (Gmail, Yahoo, iCloud) that substitutes for the real account password. Works with the same IMAP LOGIN command as Basic Auth, but is scoped and can be revoked independently. Required when 2FA is enabled.

Acceptable for personal use
3
OAuth 2.0 (XOAUTH2)

The user authorizes your app via a consent screen. Your app receives an access token (short-lived, typically 1 hour) which you base64-encode and pass to the IMAP AUTHENTICATE XOAUTH2 command. Tokens are refreshed with a long-lived refresh token. The only viable method for multi-user production apps.

Required for production

When to use which: use app passwords during local development and for personal tooling. Use OAuth 2.0 XOAUTH2 for any multi-user integration - it is the only method that scales, because you never store user passwords, and each token can be revoked without changing the user's password. For Gmail, Google has been progressively restricting Basic Auth for "less secure apps" since 2022. For Microsoft/Outlook, Basic Auth deprecation is scheduled for December 2026 across all tenants (see the next section).

For a deep-dive on OAuth flows - including token exchange, refresh logic, and scopes - see our guide on OAuth for email APIs. For Microsoft-specific OAuth setup, see Microsoft Graph OAuth for Outlook.

Action Required 2026

The 2026 problem: Microsoft Basic Auth deprecation (Dec 2026)

If your IMAP integration connects to Microsoft 365 or Outlook accounts using a username and password directly, you are on a countdown clock. Microsoft has announced the final end-of-life date for Basic Authentication across IMAP, POP3, and SMTP for all tenants.

Microsoft Basic Auth End-of-Life: December 2026

According to Microsoft Learn and the Microsoft Community Hub announcement, Exchange Online will fully disable Basic Authentication for IMAP, POP3, and SMTP in December 2026 across all tenants - including those with existing exemptions. Any IMAP client or server-side integration still using username/password authentication will stop working. There is no further extension available.

Action steps to migrate before the deadline

1
Audit your integrations

Search your codebase for IMAP connections that use login(username, password) or AUTH PLAIN. Check Microsoft Entra ID (formerly Azure AD) sign-in logs for IMAP Basic Auth activity.

2
Register an app in Microsoft Entra ID

Create an app registration at portal.azure.com with the IMAP.AccessAsUser.All (delegated) or IMAP.AccessAsApp (application) permission. See Microsoft Graph OAuth for Outlook for a step-by-step walkthrough.

3
Implement OAuth 2.0 token acquisition

Use MSAL (Microsoft Authentication Library) to acquire access tokens. Implement token refresh logic - Microsoft tokens expire after 1 hour and you need a refresh token flow to maintain long-lived IMAP sessions without user re-authentication.

4
Replace LOGIN with AUTHENTICATE XOAUTH2

Replace the IMAP LOGIN command with AUTHENTICATE XOAUTH2 using a base64-encoded token string. See the full code sample in the XOAUTH2 section below.

5
Test in a staging tenant before deadline

Microsoft provides a way to disable Basic Auth early on a per-tenant basis - use this to test your OAuth flow before the December 2026 forced cutoff, so you are not debugging production issues under deadline pressure.

If you manage IMAP connections for multiple Microsoft 365 users - a common scenario for CRM, ATS, or sales automation tools - the migration complexity compounds quickly. You need to handle OAuth consent flows for each user, store and refresh tokens securely, and deal with conditional access policies that may block your app in some tenants. This is one of the core reasons developers choose a managed IMAP API rather than maintaining raw connections themselves.

Microsoft Basic Auth deadline approaching. Build a future-proof OAuth flow today with Unipile's unified email API - we handle token refresh, multi-tenant auth, and XOAUTH2 for you.

Build a future-proof OAuth flow
Unipile - XOAUTH2 Code Block
OAuth 2.0 Code

Connecting via OAuth XOAUTH2

XOAUTH2 is the SASL mechanism that allows you to authenticate an IMAP server connection using an OAuth 2.0 access token instead of a password. The token is obtained through the standard OAuth authorization code flow (or client credentials for service accounts), base64-encoded into a specific format, and passed to the AUTHENTICATE XOAUTH2 IMAP command.

Gmail logoGmail (Google)
Outlook logoMicrosoft 365
gmail_xoauth2.py
import imaplib, base64, json from google.oauth2.credentials import Credentials from google.auth.transport.requests import Request # Load previously obtained OAuth credentials # (from google-auth-oauthlib flow) creds = Credentials( token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN, token_uri="https://oauth2.googleapis.com/token", client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scopes=["https://mail.google.com/"] ) # Refresh token if expired if creds.expired: creds.refresh(Request()) # Build XOAUTH2 string: "user={email}\x01auth=Bearer {token}\x01\x01" user_email = "user@gmail.com" auth_string = f"user={user_email}\x01auth=Bearer {creds.token}\x01\x01" auth_b64 = base64.b64encode(auth_string.encode()).decode() # Open IMAP connection and authenticate with imaplib.IMAP4_SSL("imap.gmail.com", 993) as imap: imap.authenticate("XOAUTH2", lambda _: auth_b64) imap.select("INBOX") print("Connected via XOAUTH2")
outlook_xoauth2.py
import imaplib, base64 from msal import ConfidentialClientApplication # Acquire token via MSAL (client credentials flow for service accounts) # For user-delegated access use the auth code flow instead app = ConfidentialClientApplication( client_id=CLIENT_ID, authority=f"https://login.microsoftonline.com/{TENANT_ID}", client_credential=CLIENT_SECRET ) result = app.acquire_token_for_client( scopes=["https://outlook.office365.com/.default"] ) access_token = result["access_token"] # Build XOAUTH2 string user_email = "user@company.com" auth_string = f"user={user_email}\x01auth=Bearer {access_token}\x01\x01" auth_b64 = base64.b64encode(auth_string.encode()).decode() # Connect to Outlook IMAP with imaplib.IMAP4_SSL("outlook.office365.com", 993) as imap: imap.authenticate("XOAUTH2", lambda _: auth_b64) imap.select("INBOX") print("Connected via XOAUTH2 to Outlook")

Key differences between Gmail and Microsoft XOAUTH2: Gmail requires the https://mail.google.com/ scope (full Gmail access). Microsoft requires IMAP.AccessAsUser.All (delegated) or IMAP.AccessAsApp (application). The base64 XOAUTH2 string format is identical for both providers: user={email}\x01auth=Bearer {token}\x01\x01.

One critical implementation detail: tokens expire after 3600 seconds. A long-running IMAP IDLE session (see the next section) will receive an authentication error when the token expires mid-session. You need to catch the AUTHENTICATIONFAILED error, refresh the token using your refresh token, then re-establish the IMAP connection. This retry loop is non-trivial and is a primary reason why teams choose a managed API like Unified Email API guide instead of raw IMAP connections.

For a complete OAuth setup guide for Microsoft, including conditional access policy considerations, see our Microsoft Graph OAuth for Outlook guide.

OAuth XOAUTH2 in 10 lines. Unipile handles token acquisition, refresh, and IMAP re-authentication automatically. You focus on reading emails, not on connection management.

Build OAuth XOAUTH2 in 10 lines with Unipile
Real-time Sync

IDLE, polling and push notifications: keeping the IMAP connection alive

Once you have an authenticated IMAP server connection, the next challenge is detecting new messages efficiently without hammering the server with constant requests. There are three patterns in use today - each with different latency, complexity, and infrastructure requirements.

Method How it works Latency Infrastructure Best for Rating
IMAP IDLE (RFC 2177) Client issues IDLE command; server sends EXISTS/RECENT notifications over the open TCP connection when new mail arrives. Client must send DONE + re-issue IDLE every 29 minutes (server timeout). ~1-5 seconds 1 persistent TCP connection per mailbox. Requires a dedicated thread or async loop. Single-user tools, desktop clients, low-latency monitoring Good
Polling (NOOP / CHECK) Client reconnects periodically, issues SELECT + SEARCH UNSEEN to look for new messages, then disconnects. Simple and stateless. Equal to poll interval (typically 1-15 min) Stateless. Works behind NAT/firewalls. No persistent connection. Batch processing, high-latency acceptable, environments where persistent connections are blocked Acceptable
Provider push (Gmail Pub/Sub, MS Graph webhooks) Provider sends HTTP notification to your webhook endpoint when new mail arrives. No IMAP connection needed at rest. Gmail uses Google Cloud Pub/Sub; Microsoft uses MS Graph change notifications. Near real-time (<1 second typical) Requires a public HTTPS endpoint and Pub/Sub subscription. No persistent IMAP connection at rest. High-scale multi-account production systems, serverless architectures Best at scale

IDLE is the right choice for simple integrations where you control a small number of accounts. The main gotchas: you must reconnect before the 29-minute IDLE timeout (Gmail enforces this strictly), and you need separate IMAP connections for each mailbox - which becomes expensive at hundreds or thousands of accounts.

Provider push notifications are the correct architecture for production multi-account systems. Gmail's Pub/Sub integration and Microsoft Graph's subscription webhooks both deliver near-real-time notifications without requiring a persistent IMAP connection for each account. The trade-off: you still need to open an IMAP connection to fetch the actual message body when notified, which means your IMAP connection code is still needed - just not kept open continuously. For reading email messages via API, see our guide on reading emails via API and sending emails via API.

Unipile - IMAP Troubleshooting Matrix
Troubleshooting

Troubleshooting matrix: timeouts, handshake failures, auth errors, rate limits

Below is a structured reference for the most common IMAP server connection errors. Match the symptom (error message or observable behavior) to the likely cause and the recommended fix.

Symptom / Error Category Likely Cause Fix
Connection refused on port 993 Connection Wrong host, IMAP disabled in provider settings, or firewall blocking outbound 993 Verify host from the table above. Enable IMAP in provider settings (Gmail: Settings > Forwarding and POP/IMAP). Check firewall/proxy for outbound TCP 993.
SSL handshake timeout / CERTIFICATE_VERIFY_FAILED TLS Expired or self-signed certificate, outdated CA bundle, wrong port (143 instead of 993) Use ssl.create_default_context() (Python) - do NOT pass ssl._create_unverified_context() in production. Update your CA bundle (pip install certifi). Confirm you are connecting to port 993.
AUTHENTICATIONFAILED / [AUTHENTICATIONFAILED] Invalid credentials Auth Wrong password, app password not generated, 2FA enabled but app password not used, Basic Auth blocked by provider Generate an app-specific password from the provider's security settings. If using Gmail, ensure "Less secure app access" is not the method - use app password or OAuth. For Microsoft, check if Basic Auth is disabled for the tenant.
AUTHENTICATE XOAUTH2 - invalid_token OAuth Access token expired (tokens last 3600s), malformed base64 XOAUTH2 string, wrong scope Refresh the access token before connecting. Verify the XOAUTH2 string format: user={email}\x01auth=Bearer {token}\x01\x01. Check scope: Gmail needs https://mail.google.com/; Outlook needs IMAP.AccessAsUser.All.
imaplib.error: command AUTHENTICATE illegal in state AUTH State Attempting to authenticate when already in Authenticated state, or after a failed auth attempt without resetting Close and reopen the IMAP connection before retrying authentication. Never retry auth on the same connection after a failure.
IMAP connection drops after 29 minutes of IDLE IDLE Server-enforced IDLE timeout (standard: 30 minutes per RFC 2177). Gmail enforces 29 minutes. Issue DONE at 25-27 minutes, then immediately re-issue IDLE. Use a background thread or async task with a 25-minute heartbeat timer.
[OVERQUOTA] or Too many simultaneous connections Rate Limit Provider-imposed connection limit exceeded. Gmail allows 15 simultaneous IMAP connections per account; Outlook varies by plan. Use connection pooling. For Gmail: max 15 concurrent connections per account. Close idle connections explicitly (LOGOUT) rather than dropping TCP. Implement exponential backoff on connection errors.
NO [ALERT] Please log in via your web browser Auth Google security challenge triggered (unusual access pattern, new IP, captcha required) Log in via browser from the same network to clear the security challenge. Consider switching to OAuth - app-password access from unknown IPs triggers these challenges more often than OAuth.
BYE Autologout; idle for too long Connection IMAP connection in Authenticated state (mailbox not selected) was idle for too long After authentication, immediately SELECT a mailbox or issue IDLE. Implement reconnect logic when you receive BYE.
FETCH returns empty body / nil parts Protocol Message was expunged between SEARCH and FETCH, or UID mismatch after folder re-scan Always use UID FETCH (not sequence numbers) for multi-step operations. Handle None return values from FETCH gracefully. Re-issue SEARCH after a reconnect to get fresh UIDs.
Connection refused on port 993 Connection
Likely Cause Wrong host, IMAP disabled in provider settings, or firewall blocking outbound 993.
Fix Verify host from the table above. Enable IMAP in provider settings (Gmail: Settings > Forwarding and POP/IMAP). Check firewall/proxy for outbound TCP 993.
SSL handshake timeout / CERTIFICATE_VERIFY_FAILED TLS
Likely Cause Expired or self-signed certificate, outdated CA bundle, wrong port (143 instead of 993).
Fix Use ssl.create_default_context() (Python) - do NOT pass ssl._create_unverified_context() in production. Update your CA bundle (pip install certifi). Confirm you are connecting to port 993.
AUTHENTICATIONFAILED / Invalid credentials Auth
Likely Cause Wrong password, app password not generated, 2FA enabled but app password not used, Basic Auth blocked by provider.
Fix Generate an app-specific password from the provider's security settings. If using Gmail, ensure "Less secure app access" is not the method - use app password or OAuth. For Microsoft, check if Basic Auth is disabled for the tenant.
AUTHENTICATE XOAUTH2 - invalid_token OAuth
Likely Cause Access token expired (tokens last 3600s), malformed base64 XOAUTH2 string, wrong scope.
Fix Refresh the access token before connecting. Verify the XOAUTH2 string format: user={email}\x01auth=Bearer {token}\x01\x01. Check scope: Gmail needs https://mail.google.com/; Outlook needs IMAP.AccessAsUser.All.
imaplib.error: AUTHENTICATE illegal in state AUTH State
Likely Cause Attempting to authenticate when already in Authenticated state, or after a failed auth attempt without resetting.
Fix Close and reopen the IMAP connection before retrying authentication. Never retry auth on the same connection after a failure.
IMAP connection drops after 29 minutes of IDLE IDLE
Likely Cause Server-enforced IDLE timeout (standard: 30 minutes per RFC 2177). Gmail enforces 29 minutes.
Fix Issue DONE at 25-27 minutes, then immediately re-issue IDLE. Use a background thread or async task with a 25-minute heartbeat timer.
[OVERQUOTA] or Too many simultaneous connections Rate Limit
Likely Cause Provider-imposed connection limit exceeded. Gmail allows 15 simultaneous IMAP connections per account; Outlook varies by plan.
Fix Use connection pooling. For Gmail: max 15 concurrent connections per account. Close idle connections explicitly (LOGOUT) rather than dropping TCP. Implement exponential backoff on connection errors.
NO [ALERT] Please log in via your web browser Auth
Likely Cause Google security challenge triggered (unusual access pattern, new IP, captcha required).
Fix Log in via browser from the same network to clear the security challenge. Consider switching to OAuth - app-password access from unknown IPs triggers these challenges more often than OAuth.
BYE Autologout; idle for too long Connection
Likely Cause IMAP connection in Authenticated state (mailbox not selected) was idle for too long.
Fix After authentication, immediately SELECT a mailbox or issue IDLE. Implement reconnect logic when you receive BYE.
FETCH returns empty body / nil parts Protocol
Likely Cause Message was expunged between SEARCH and FETCH, or UID mismatch after folder re-scan.
Fix Always use UID FETCH (not sequence numbers) for multi-step operations. Handle None return values from FETCH gracefully. Re-issue SEARCH after a reconnect to get fresh UIDs.

Stop debugging IMAP errors. Unipile surfaces clean email objects via REST - no IMAP state machine, no token refresh logic, no connection pooling to manage.

Stop debugging IMAP - Start building
Production Reality

Why production-grade IMAP at scale is harder than it looks

Opening a single IMAP server connection to a Gmail inbox is 15 lines of Python. Scaling that to hundreds or thousands of users in a production SaaS product is a fundamentally different engineering problem. Here is an honest breakdown of where raw IMAP connections create non-obvious complexity.

OAuth token lifecycle management

Access tokens expire every 3600 seconds. For 1,000 linked accounts, you need a background job that proactively refreshes tokens before expiry, handles refresh token rotation (Google rotates them under certain conditions), and manages the case where a user revokes access - which you only discover at the next token use.

Multi-account IMAP connection state

Each active IMAP session holds state: current selected mailbox, last seen UID, IDLE timer. If your server restarts, you lose all this state and must re-sync from scratch - potentially fetching thousands of messages you have already processed. You need a persistent state store per account.

Error retry and exponential backoff

Transient failures (network blips, server 500s, rate limit responses) require retry logic with exponential backoff and jitter. Naive retry loops hammer providers and result in temporary IP bans. You need a proper job queue with configurable retry delays and dead-letter handling for permanently failed accounts.

Credential storage and encryption at rest

OAuth refresh tokens are long-lived credentials that grant full email access. They must be encrypted at rest using a KMS-backed key, access-controlled at the infrastructure level, and rotated if there is any indication of a breach. This is a significant security surface area that requires proper key management infrastructure.

Rate limiting and per-account quotas

Gmail limits concurrent IMAP connections to 15 per account. If your application opens more connections than allowed, it receives OVERQUOTA errors. At the same time, providers also impose bandwidth quotas on total data transferred. You need connection pooling, request throttling, and per-account rate tracking.

Provider-specific edge cases

Gmail labels vs. IMAP folders, Outlook's non-standard folder naming for Sent/Deleted, IMAP servers that return CAPABILITY responses that do not match what they actually support, and servers that silently drop connections during FETCH operations on large attachments. Each provider has a unique set of quirks that only surface in production.

This is not an argument against building a custom IMAP integration - for a single-provider, single-user tool, raw IMAP is perfectly reasonable. But for any product that needs to read and sync email across multiple providers and multiple user accounts, the operational overhead of maintaining a custom IMAP layer typically exceeds the cost of using a dedicated email API. The Unified Email API guide covers the architectural trade-offs in detail.

Production email sync without the IMAP overhead. Unipile handles connection pooling, token refresh, error retry, and multi-provider normalization - you just call the API.

Build at scale without IMAP overhead
Unipile - IMAP BOFU (Light)
5-Minute Quickstart

Building an IMAP integration without managing the connection: Unipile

If you have read this far, you have a clear picture of what it takes to maintain raw IMAP connections in production: OAuth token refresh loops, per-account state management, connection pooling, retry logic, and provider-specific quirks for Gmail, Outlook, and IMAP servers. Unipile abstracts this entire layer and gives you a single REST API to read, send, and sync email across all three, with a 5-minute quickstart and less than 10 lines of code per operation.

OAuth handled for you

Unipile manages the full OAuth flow for Gmail and Microsoft 365: token acquisition, refresh, and rotation. You never touch a refresh token directly.

Gmail, Outlook, and IMAP unified

One API, one response schema. Read emails from a Gmail inbox and an IMAP corporate server with the same GET /emails call. No provider-specific parsing.

Real-time webhooks, no IDLE loop

Receive HTTP notifications when new emails arrive. No persistent IMAP connection to manage, no 29-minute IDLE timeout to handle, no dedicated thread per account.

Multi-account from day one

Link user accounts via Unipile's hosted OAuth flow. Each linked account gets its own account_id. Scale from 1 to 10,000 linked accounts without changing your integration code.

SOC 2 Type II + CASA Tier 2

Credentials encrypted at rest with KMS-backed keys. Unipile is SOC 2 Type II certified and CASA Tier 2 assessed. No IMAP passwords or OAuth tokens stored in your database.

unipile_quickstart.py
import requests BASE_URL = "https://api7.unipile.com:13047/api/v1" HEADERS = {"X-API-KEY": "your-unipile-api-key"} # Step 1: List all linked accounts accounts = requests.get( f"{BASE_URL}/accounts", headers=HEADERS ).json() account_id = accounts["items"][0]["id"] # Step 2: Read inbox emails emails = requests.get( f"{BASE_URL}/emails", headers=HEADERS, params={"account_id": account_id, "limit": 10} ).json() for email in emails["items"]: print(email["subject"], email["from_attendee"]) # No IMAP connection, no token refresh, # no SSL context, no state machine.
Works with Gmail, Outlook, and IMAP: same code
Works with: Gmail Outlook IMAP
SOC 2 Type II CASA Tier 2 Credentials encrypted at rest GDPR compliant
FAQ

Frequently Asked Questions

Common questions about IMAP server connections, ports, authentication, and OAuth migration.

1
What is an IMAP server connection?

An IMAP server connection is a persistent TCP session between an email client and a mail server that uses the Internet Message Access Protocol to synchronize, retrieve, and manage email messages stored on the server - without downloading or deleting them locally. Unlike POP3, IMAP keeps messages on the server and synchronizes state (read, flagged, moved) across all connected devices. For developers, it is the foundational protocol for building email integrations that work across Gmail, Outlook, and any standard IMAP API.

2
Which port should I use for IMAP: 143 or 993?

Use port 993 for IMAP over SSL/TLS (implicit TLS). This is the modern standard and is required by all major cloud providers including Gmail and Outlook. Port 143 is for STARTTLS upgrades and is only appropriate for self-hosted mail servers. Never connect to a cloud mail server on port 143 in production - most now refuse such connections entirely. If you are unsure, always default to port 993 with ssl=True.

3
Do I need SSL/TLS for IMAP?

Yes, without exception. SSL/TLS is mandatory for any IMAP server connection that transmits credentials. Modern mail servers refuse plain-text connections entirely. RFC 9051 (IMAP4rev2) formally requires TLS for all authenticated sessions. Always use port 993 with implicit TLS for cloud providers. If connecting to a self-hosted server on port 143, you must upgrade to TLS using the STARTTLS command and verify the server certificate - never use ssl._create_unverified_context() in production.

4
What is the IMAP server address for Gmail?

The IMAP server address for Gmail is imap.gmail.com on port 993 with SSL/TLS. Before connecting, you must enable IMAP access in Gmail Settings under "Forwarding and POP/IMAP". Authentication requires either an app-specific password (if 2FA is enabled) or OAuth 2.0 XOAUTH2 with the scope https://mail.google.com/. Google has restricted Basic Auth for new apps and strongly recommends OAuth for any programmatic IMAP access.

5
What is the IMAP server address for Outlook and Microsoft 365?

The IMAP server address for both personal Outlook.com accounts and Microsoft 365 business accounts is outlook.office365.com on port 993 with SSL/TLS. Note that Microsoft is ending support for Basic Authentication (username/password) for IMAP in December 2026. All integrations must migrate to OAuth 2.0 XOAUTH2 before that deadline. See our Microsoft Graph OAuth for Outlook guide for migration steps.

6
Do I need an app password to connect to IMAP?

You need an app-specific password if your account has two-factor authentication enabled and you are using Basic Auth for IMAP. App passwords are 16-character tokens generated from your provider's security settings (Google Account security page for Gmail, Apple ID for iCloud) that substitute for your real password without granting full account access. For production multi-user applications, OAuth 2.0 is strongly preferred over app passwords - it is more secure, does not require storing any user credential in your application, and is the only method that remains valid after the Microsoft Basic Auth deprecation in December 2026.

7
Is IMAP Basic Authentication deprecated in 2026?

Yes, for Microsoft services. Microsoft has confirmed the final end-of-life for Basic Authentication across IMAP, POP3, and SMTP in Exchange Online in December 2026, affecting all tenants including those with existing exemptions. Any integration using username/password authentication against Outlook or Microsoft 365 IMAP will stop working after that date. Google has already restricted Basic Auth access for Gmail and requires app passwords or OAuth for any programmatic access since 2022. If your IMAP integration connects to Microsoft accounts, you must migrate to OAuth 2.0 XOAUTH2 before December 2026.

8
How do I connect to IMAP with OAuth 2.0?

To connect to an IMAP server with OAuth 2.0, you use the XOAUTH2 SASL mechanism. After obtaining an access token through the standard OAuth authorization code flow, encode the string user={email}\x01auth=Bearer {token}\x01\x01 as base64, then pass it to the AUTHENTICATE XOAUTH2 IMAP command. For Gmail, the required scope is https://mail.google.com/. For Microsoft 365, use MSAL to acquire a token with the IMAP.AccessAsUser.All scope. Access tokens expire after 3600 seconds and must be refreshed before reconnecting - implement a token refresh check before each new IMAP session. See the full code samples in the XOAUTH2 section above.

Still have questions about IMAP integration? Our team can help you navigate provider quirks, OAuth migration, and multi-account architecture.

Talk to an expert
en_USEN