Skip to content

Bug: IndexerJob fails with cURL error 26 on systems with server-side encryption enabled #148

@TheSpaceGod

Description

@TheSpaceGod

Which version of Nextcloud are you using?

31.0.7

Which version of PHP context_chat are you using?

8.3.23

Which version of backend context_chat are you using?

4.4.0

Which browser are you using? In case you are using the phone App, specify the Android or iOS version and device please.

Chrome lastest version

Nextcloud deployment method?

AIO

Describe the Bug

Related Issue: nextcloud/context_chat_backend#176
NOTE: This ticket was generated with the help of AI.

Expected Behavior
The IndexerJob should successfully read the files, send them to the context_chat_backend via the /loadSources endpoint, and complete without errors. The files should become indexed and available for context-aware features.

Actual Behavior
The IndexerJob fails consistently for users with encrypted files. The job logs a "Temporary problem with indexing" error and is rescheduled, leading to a loop of failed attempts and high server load.
The nextcloud.log file is populated with the following exception:

{
  "reqId": "CHkzYh7obz7MBfwvGQ6O",
  "level": 3,
  "time": "2025-07-23T00:13:03+00:00",
  "remoteAddr": "",
  "user": "--",
  "app": "no app in context",
  "method": "",
  "url": "--",
  "message": "[IndexerJob] Temporary problem with indexing",
  "userAgent": "--",
  "version": "31.0.7.1",
  "exception": {
    "Exception": "RuntimeException",
    "Message": "Error during request to Context Chat Backend (ExApp): cURL error 26: client read function EOF fail, only 36306591/36943199 of needed bytes read (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://context_chat_backend:23000/loadSources",
    "Code": 0,
    "Trace": "[...]",
    "File": "/var/www/html/custom_apps/context_chat/lib/Service/LangRopeService.php",
    "Line": 132
  }
}

The key message is cURL error 26: client read function EOF fail, which indicates that the client (Nextcloud) stopped sending data before the amount specified in the Content-Length header was reached.

Technical Analysis: Root Cause
The root cause of this error is a mismatch between the calculated Content-Length of the HTTP request and the actual size of the data being streamed when Nextcloud's server-side encryption is active.

Incorrect Size Calculation:
The IndexerJob calculates the size of each file by directly querying the storage for the size of the physical file on disk. The code responsible appears to be in OCA\ContextChat\BackgroundJobs\IndexerJob.php and uses a method similar to:

$file->getStorage()->filesize($file->getInternalPath());

On an encrypted system, this call returns the size of the encrypted file, which is larger than the original file due to encryption headers, IV, and padding.

Correct Content Streaming:
However, when OCA\ContextChat\Service\LangRopeService.php prepares the cURL handle to upload the file, it correctly uses Nextcloud's Virtual File System (VFS) to get the file's content, likely via $file->fopen('r') or $file->getContent(). This VFS method transparently decrypts the file, meaning the data stream sent in the request body is the smaller, original file content.

The Resulting Mismatch:
The Content-Length header promises a larger size (the encrypted size).
The request body contains the smaller data stream (the decrypted content).
When the PHP script finishes streaming the decrypted content, cURL is still waiting for the "missing" bytes (the encryption overhead). The script terminates, cURL receives an EOF prematurely, and it correctly throws error 26.
This is not a simple timeout issue (error 28), but a data source failure, which strongly points to this Content-Length discrepancy.

Proposed Solution
The fix is to ensure that the file size is also retrieved through the Nextcloud VFS, which will return the decrypted size, matching the content stream.
The file size calculation in OCA\ContextChat\BackgroundJobs\IndexerJob.php should be changed from the direct storage call to the VFS-aware method:
Change from:

$file->getStorage()->filesize($file->getInternalPath());

Change to:

$file->getSize();

This will ensure that the calculated Content-Length accurately reflects the size of the decrypted data being sent, resolving the cURL error 26 for all users on encrypted instances.

Thank you for your work on this valuable application.

To Reproduce

  1. Set up a Nextcloud instance with the Default encryption module (server-side encryption) enabled.
  2. Install and enable the Context Chat application.
  3. Upload several files of various types (e.g., PDF, DOCX, TXT) to a user's account.
  4. Allow the background cron job to run, which will eventually trigger OCA\ContextChat\BackgroundJobs\IndexerJob. (Alternatively, trigger it manually with occ).
  5. Observe the nextcloud.log file.

PHP logs (Warning these might contain sensitive information)

No response

Ex-App logs (Warning these might contain sensitive information)

No response

Server logs (if applicable)

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions