Overview
Kayako Classic email retrieval from Microsoft Office 365 using IMAP over OAuth can intermittently hang during POP3/IMAP parser execution. In affected environments, the parser may consume sustained 100% CPU, exceed PHP or web server execution time limits, and fail to ingest new emails.
The issue occurs while the IMAP parser is opening or selecting the mailbox. The stack trace may show repeated execution inside readLine() and decodeLine() in Kayako Classic’s bundled IMAP protocol dependency.
A confirmed workaround is to apply a small code change in decodeLine() so the input buffer advances when an empty token is encountered. This prevents the parser from entering an infinite loop and restores IMAP mail retrieval in affected environments.
Solution (Workaround)
Issue
Kayako Classic mail pickup from Microsoft Office 365 using IMAP over OAuth may intermittently hang and eventually fail with either a PHP execution timeout or an IIS/FastCGI timeout, depending on the hosting environment.
Common affected scenario
- Kayako Classic / Kayako Classic Fusion is configured with an Office 365 IMAP OAuth email queue.
- The queue’s Verify Connection test succeeds.
- The mailbox message count may be displayed successfully.
- Running the scheduled or manual parser hangs, times out, or returns an error.
- No new emails are fetched, and tickets are not created from the mailbox.
Common symptoms
- Manual parser run never completes.
- Scheduled parser appears stuck or repeatedly fails.
- Sustained 100% CPU during parser execution.
- Email queues back up.
- New tickets are not created from incoming emails.
- The parser may fail even when the mailbox contains only a small test email.
Possible error messages
PHP maximum execution timeout
PHP Fatal error: Maximum execution time of 600 seconds exceeded in .../vendor/kayako-zend/zend-mail-kayako/src/Protocol/Imap.php on line 186
The stack trace commonly ends in readLine() and decodeLine().
IIS / FastCGI timeout
HTTP Error 500.0 - Internal Server Error
<php_path>\php-cgi.exe - The FastCGI process exceeded configured request timeout
Error Code: 0x80070102
This may occur when running the manual parser URL, for example:
https://your_instance.domain.com/support/cron/index.php?/Parser/ParserMinute/POP3IMAP
Why Verify Connection can succeed while the parser still fails
Verify Connection confirms that Kayako can authenticate, connect to the mailbox, and read basic mailbox information such as message count. The full parser run performs additional mailbox opening, message retrieval, and processing. The failure described in this article occurs during parser execution, not during the initial OAuth authentication or connection test.
Quick isolation checks before patching
Before changing code, use these checks to confirm that the behavior matches this issue:
- Confirm the affected queue is configured as an IMAP OAuth queue for Office 365.
- Confirm Verify Connection succeeds and shows the mailbox message count.
- Temporarily disable other POP3/IMAP queues, leaving only one test IMAP queue enabled.
- Reduce mailbox load:
- Move existing emails out of the folder being polled.
- Leave only one small plain-text test email with no attachment.
- Run the manual parser URL again.
- If the parser still hangs, consumes high CPU, or returns a timeout, proceed with the workaround below.
Workaround: Patch decodeLine() to avoid the infinite loop
Important: This workaround targets the IMAP/OAuth parser hang where execution loops in decodeLine(). It is not intended to fix separate POP3 header-parsing errors.
1) Back up the IMAP protocol file
Back up the following file before editing:
<kayako_install_path>/vendor/kayako-zend/zend-mail-kayako/src/Protocol/Imap.php
On Windows/IIS environments, the path may appear as:
<kayako_install_path>\vendor\kayako-zend\zend-mail-kayako\src\Protocol\Imap.php
Example Linux install path seen in logs: /usr/share/nginx/html/...
2) Edit decodeLine() in Imap.php
Locate this block:
if (!strlen($token)) {
continue;
}
Depending on formatting, the same block may appear with a space after the ! operator:
if (! strlen($token)) {
continue;
}
Replace the block with:
if (!strlen($token)) {
$line = substr($line, $pos + 1);
continue;
}
Or, preserving the existing spacing style:
if (! strlen($token)) {
$line = substr($line, $pos + 1);
continue;
}
3) Re-run the parser
Run the manual email parser again. For example:
https://your_instance.domain.com/support/cron/index.php?/Parser/ParserMinute/POP3IMAP
4) Validate the workaround
A successful parser run should:
- Complete without hanging.
- Stop consuming sustained 100% CPU.
- Not return the IIS HTTP 500.0 / FastCGI timeout page.
- Not fail with the PHP maximum execution time fatal error.
- Return normal parser summary output.
- Pull emails into Kayako Classic successfully.
Successful parser output may look similar to:
Running parser for Queue ID '<queue_id>': <queue_address>
Queue Total: <n>, Accepted: <n>, Rejected: <n>
Final Total: <n>, Accepted: <n>, Rejected: <n>
Also confirm that the test email is ingested into Kayako Classic and that a ticket is created as expected.
Related but separate POP3 symptom
If you switch the queue to POP3 or POP3 OAuth during testing and see an error like:
Line "<feff>Received: from <outlook_server> ..." does not match header format!
Treat this as a separate POP3/header-ingestion issue. The IMAP decodeLine() patch above is specifically for the IMAP/OAuth parser hang and is not expected to resolve POP3 header-format errors.
Defect / fix status
No official product release fix version is confirmed for this issue. Resolution in the documented cases was achieved through a local workaround patch to a bundled vendor dependency.
Important notes for Kayako Classic End of Engineering
- Kayako Classic is End of Engineering.
- This workaround modifies a file inside the bundled
vendordirectory. - The change may be overwritten by redeployments, restores, migrations, or upgrades that refresh the vendor directory.
- Keep a copy of the patched file or a small diff/patch in deployment documentation.
- If the timeout returns after a redeploy or upgrade, verify whether the change in
Imap.phpstill exists.
Environment noted in documented cases
- Kayako Classic / Kayako Classic Fusion
- Kayako Classic Fusion 4.98.9 in one documented case
- Microsoft Office 365 IMAP over OAuth
- IMAP host:
outlook.office365.com - IMAP port:
993 - IMAP security: TLS
- PHP 7.3.x in one documented IIS/FastCGI case
- IIS/FastCGI in one documented case
- Linux/nginx-style paths observed in another documented case
Frequently Asked Questions
- 1. Are the IIS/FastCGI timeout and the 100% CPU PHP timeout the same issue?
-
They can be different symptoms of the same underlying IMAP parser hang. In IIS/FastCGI environments, the request may fail with an HTTP 500.0 timeout. In other environments, PHP may report a maximum execution time fatal error. Both can occur when the parser loops inside
decodeLine(). - 2. How do I recognize this specific IMAP/OAuth hang issue?
-
You typically see the parser hang, consume sustained 100% CPU, or eventually fail with a timeout. The stack trace may end in
readLine()anddecodeLine()inside:vendor/kayako-zend/zend-mail-kayako/src/Protocol/Imap.php - 3. Why does Verify Connection succeed if the parser is broken?
-
Verify Connection only confirms that Kayako can authenticate and connect to the mailbox. The parser performs additional retrieval and processing work. This issue occurs during the parser run, so OAuth authentication and the initial connection test may still succeed.
- 4. Where exactly do I apply the workaround change?
-
Edit:
<kayako_install_path>/vendor/kayako-zend/zend-mail-kayako/src/Protocol/Imap.phpUpdate the
decodeLine()empty-token block so the line buffer advances before the loop continues:if (!strlen($token)) { $line = substr($line, $pos + 1); continue; } - 5. How can I verify the workaround worked?
-
Run the manual parser again and confirm that:
- The parser completes without hanging.
- CPU does not remain stuck at 100%.
- No PHP or IIS/FastCGI timeout is returned.
- Parser summary output is displayed.
- New emails are successfully pulled into Kayako Classic.
- 6. Will increasing PHP, IIS, or FastCGI timeouts fix this?
-
Increasing timeouts may delay the failure, but it does not address the underlying parser loop. In the documented cases, the working mitigation was the
decodeLine()code change. - 7. I tried switching to POP3 OAuth and now I get
Line "<feff>Received: ..."does not match header format. Is that the same issue? -
No. That indicates a separate POP3 header-parsing failure mode. The IMAP
decodeLine()workaround is specifically for the IMAP/OAuth parser hang and is not intended to fix POP3 header-format errors. - 8. Will this change be overwritten later?
-
Yes. Because the change is made inside a bundled vendor dependency, it may be overwritten by redeployments, restores, migrations, or upgrades that replace the
vendordirectory. Keep a copy of the patched file or a documented diff so it can be reapplied if needed. - 9. What should I collect if the IMAP hang continues after applying the change?
-
Collect the following:
- Full manual parser output.
- Matching PHP, web server, or IIS/FastCGI error logs from the same timeframe.
- Confirmation that the affected queue is an IMAP OAuth queue, not a POP3 test queue.
- Confirmation that the
decodeLine()patch is still present inImap.php. - Mailbox load details, including whether the parser was tested with a single small plain-text email.
Go to Kayako
Priyanka Bhotika
Comments