GUIs are nice, but command line mail clients make me more productive with reduced stress on the human side of the UI (i.e. my fingers and wrists). On Linux, Pine, and now alpine have served me well for many years, despite some limitations in an increasingly HTML-bloated email world. The following is one issue that has annoyed me, related to some behind-the-scenes upgrades by my email provider some years ago. As usual, the the troubleshooting journey proved to be instructive about the behaviour of IMAP servers — specifically my provider’s implementation (based on Dovecot) of session timeouts.
The scenario: you’re logged in, browsing your INBOX or composing an email and suddenly get the error:
MAIL FOLDER "INBOX" CLOSED DUE TO ACCESS ERROR
which forces you to re-open the folder. Additionally, when replying to email, once the INBOX is closed, flag updates (such as Answered) don’t apply any more. This seemed to happen randomly, and for other folders I have open (not just in the INBOX). The error at first suggests a lock contention, but research suggested it was actually the connection being closed, and that forcing more frequent mail checks would help.
The first step was to establish a client-independent IMAP connection and leave it idle:
$ time openssl s_client -connect mailprovider:993 -quiet
... [SSL preamble snipped out ]
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.
a1 LOGIN MYUSERNAME@DOMAIN MYPASSWORD
a1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT IDLE CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS] Logged in
a2 EXAMINE INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* 955 EXISTS
* 0 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1156786977] UIDs valid
* OK [UIDNEXT 106677] Predicted next UID
* OK [HIGHESTMODSEQ 1] Highest
a2 OK [READ-ONLY] Select completed.
read:errno=0
real 2m24.046s
user 0m0.034s
sys 0m0.008s
$
(BOLD text represents commands from my end)
So the connection was killed ~ 2 minutes or so later. This gave me an idea of what to tune alpine for. However, it seems to violate RFC2683:
From: https://www.ietf.org/rfc/rfc2683.txt:
When the server wants to sever a connection it’s usually due to an
inactivity timeout or is because a situation has arisen that has
changed the state of the mail store in a way that the server can not
communicate to the client. The server should send an untagged BYE
response to the client and then close the socket. Sending an
untagged BYE response before severing allows the server to send a
human-readable explanation of the problem to the client, which the
client may then log, display to the user, or both (see section 7.1.5
of [RFC-2060]).Regarding inactivity timeouts, there is some controversy. Unlike
POP, for which the design is for a client to connect, retrieve mail,
and log out, IMAP’s design encourages long-lived (and mostly
inactive) client/server sessions. As the number of users grows, this
can use up a lot of server resources, especially with clients that
are designed to maintain sessions for mailboxes that the user has
finished accessing. To alleviate this, a server may implement an
inactivity timeout, unilaterally closing a session (after first
sending an untagged BYE, as noted above). Some server operators have
reported dramatic improvements in server performance after doing
this. As specified in [RFC-2060], if such a timeout is done it must
not be until at least 30 minutes of inactivity. The reason for this
specification is to prevent clients from sending commands (such as
NOOP) to the server at frequent intervals simply to avert a too-early
timeout. If the client knows that the server may not time out the
session for at least 30 minutes, then the client need not poll at
intervals more frequent than, say, 25 minutes.
In alpine, the most relevant setting seemed to be:
Mail Check Interval
This option specifies, in seconds, how often Alpine will check for new mail. If set to zero, new-mail checking is disabled. (You can always manually force a new-mail check by typing ^L (Ctrl-L), which is also the command to refresh the screen, or by typing the Next command when the current message is the last message of the folder.) There is a minimum value for this option, normally 15 seconds. The default value is normally 150 seconds. The higher you set this option, the easier it is on the server.
I set this to 110 seconds (mail-check-interval=110 in ~/.pinerc) based on the timing test above, and that resolved the issue for the most part. There are still some situations where I’m in other folders, or composing a long email, where this still crops up. Alpine is old, and I suspect multi-threading isn’t well supported. So I’ll blame it on that for now. At least the most annoying part is sufficiently resolved.
There is also a “Folder Reopen Rule” that I also set to “Always”, but I don’t think it’s relevant.
Note that more modern clients support the IMAP IDLE command https://tools.ietf.org/html/rfc2177 (also referred to as Push capability)
The Internet Message Access Protocol [IMAP4] requires a client to
poll the server for changes to the selected mailbox (new mail,
deletions). It’s often more desirable to have the server transmit
updates to the client in real time. This allows a user to see new
mail immediately. It also helps some real-time applications based on
IMAP, which might otherwise need to poll extremely often (such as
every few seconds). (While the spec actually does allow a server to
push EXISTS responses aysynchronously, a client can’t expect this
behaviour and must poll.)This document specifies the syntax of an IDLE command, which will
allow a client to tell the server that it’s ready to accept such
real-time updates.
I really should switch to Mutt or something else with such support … On Android, I use a far more modern client (K-9 Mail — the only one I find meets my needs). I doubt most users would notice IMAP session timeouts, because every modern IMAP capable mail client should