{"record":{"id":"813b85a877814bbb","repo":"RocketChat/Rocket.Chat","slug":"fetch-error","errorCode":null,"errorMessage":"Fetch error","messagePattern":"Fetch error","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/server/email/IMAPInterceptor.ts","lineNumber":202,"sourceCode":"\t\t\t\t\tsimpleParser(new Readable().wrap(stream), (_err, email) => {\n\t\t\t\t\t\tif (this.options.rejectBeforeTS && email.date && email.date < this.options.rejectBeforeTS) {\n\t\t\t\t\t\t\tlogger.error({ msg: 'Rejecting email on inbox', user: this.config.user, subject: email.subject });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.emit('email', email);\n\t\t\t\t\t\tif (this.options.deleteAfterRead) {\n\t\t\t\t\t\t\tthis.imap.seq.addFlags(email, 'Deleted', (err) => {\n\t\t\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\t\t\tlogger.warn({ msg: 'Mark deleted error', err });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\tmsg.once('body', bodycb);\n\t\t\t};\n\t\t\tconst errorcb = (err: Error): void => {\n\t\t\t\tlogger.warn({ msg: 'Fetch error', err });\n\t\t\t\treject(err);\n\t\t\t};\n\t\t\tconst endcb = (): void => {\n\t\t\t\tresolve(out);\n\t\t\t};\n\t\t\tconst fetch = this.imap.fetch(emailIds, {\n\t\t\t\tbodies: ['HEADER', 'TEXT', ''],\n\t\t\t\tstruct: true,\n\t\t\t\tmarkSeen: this.options.markSeen,\n\t\t\t});\n\n\t\t\tfetch.on('message', messagecb);\n\t\t\tfetch.on('error', errorcb);\n\t\t\tfetch.on('end', endcb);\n\t\t});\n\t}\n\n\t// Fetch all UNSEEN messages and pass them for further processing","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/email/IMAPInterceptor.ts#L184-L220","documentation":"The IMAP interceptor's batch fetch (imap.fetch over a set of message ids, requesting HEADER/TEXT bodies and structure) emitted an 'error' event. Unlike the per-message flag warning, this handler rejects the enclosing promise, so the whole poll cycle for those emailIds fails and the caller of getEmails receives the rejection. Typical causes are a dropped connection mid-fetch, sequence numbers invalidated by concurrent mailbox changes, or server-side timeouts.","triggerScenarios":"Connection reset while streaming message bodies; another client expunging messages so sequence numbers shift under the running fetch; fetching a very large backlog exceeding the server's command timeout; server sending BYE due to inactivity/throttling.","commonSituations":"Inbound-email channel against shared IMAP hosts with aggressive timeouts; two consumers (Rocket.Chat plus a mail client) working the same mailbox; first connect after downtime fetching a huge backlog.","solutions":["Read the err text for 'BYE', 'timeout', or 'Connection error' to classify it","Reduce fetch batch size and poll frequency","Ensure only one consumer processes the mailbox","Make the polling loop catch the rejection, reconnect, and retry with backoff instead of dying"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n\tconst ids = await interceptor.getEmails();\n} catch (error) {\n\tlogger.warn({ msg: 'IMAP fetch failed, reconnecting', err: error });\n\tawait interceptor.reconnect();\n\t// retry the batch once after reconnect; then back off\n}","preventionTips":["Fetch in small batches so a mid-fetch disconnect loses little work","Ensure a single consumer per mailbox to avoid sequence-number churn from concurrent expunges","Wrap the polling loop with reconnect + backoff instead of letting one rejection kill the channel"],"tags":["imap","email","inbound-email","network","node-imap"],"backgroundTag":"imap-connection-dropped","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}