Start a conversation

Kayako Classic IMAP/OAuth Parser Hangs, High CPU, or FastCGI/PHP Timeout with Office 365 — Workaround for decodeLine() Infinite Loop

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:

  1. Confirm the affected queue is configured as an IMAP OAuth queue for Office 365.
  2. Confirm Verify Connection succeeds and shows the mailbox message count.
  3. Temporarily disable other POP3/IMAP queues, leaving only one test IMAP queue enabled.
  4. Reduce mailbox load:
    • Move existing emails out of the folder being polled.
    • Leave only one small plain-text test email with no attachment.
  5. Run the manual parser URL again.
  6. 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 vendor directory.
  • 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.php still 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() and decodeLine() 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.php

Update 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 vendor directory. 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 in Imap.php.
  • Mailbox load details, including whether the parser was tested with a single small plain-text email.
Choose files or drag and drop files
Was this article helpful?
Yes
No
  1. Priyanka Bhotika

  2. Posted
  3. Updated

Comments