Skip to content

Health check intermittently fails during repeated PDF conversions #1648

Closed

Description

@adq-talbot

Context

Our application uses Gotenberg to generate PDF files from DOCX documents.

In some cases, the application needs to generate a large number of PDFs sequentially. Before each conversion, it performs a request to the /health endpoint to check that the Gotenberg service is still available.

Description

When generating PDFs sequentially, the /health endpoint intermittently fails after several conversions, even though the Gotenberg service is still available.

The issue usually occurs after around 10–15 PDF conversions.

The PDF conversions themselves are performed sequentially: I wait for a PDF conversion to complete before starting the next one.

Reproduction

I tested the following Gotenberg versions:

8.28: issue not reproducible
8.29 → 8.36: issue reproducible

A minimal reproduction script is provided below.

The reproduction script assumes that a Gotenberg service is available at http://pdf:3000. The DOCX file used for the conversion is attached here: input.docx.

<?php

require_once 'External/autoload.php';

use GuzzleHttp\Client;

$client = new Client();
$url = 'http://pdf:3000';
$file = __DIR__ . '/input.docx';

for ($i = 1; $i <= 100; $i++) {
    echo "$i: health check... ";

    try {
        $client->get("$url/health", ['timeout' => 30]);
        echo "OK\n";

        $client->post("$url/forms/libreoffice/convert", [
            'multipart' => [[
                'name' => 'files',
                'contents' => fopen($file, 'r'),
                'filename' => 'file.docx',
            ]],
        ]);

        echo "   conversion OK\n";
    } catch (\Throwable $e) {
        echo "FAILED\n";
        echo $e::class . ': ' . $e->getMessage() . "\n";
        exit(1);
    }
}

Expected behavior

The /health endpoint should consistently return a successful response while the Gotenberg service is available, including when PDF conversions are performed sequentially.

Actual behavior

After several PDF conversions, the /health request can fail even though the Gotenberg service is still available.

The issue is intermittent, but typically occurs after around 10–15 conversions.

Adding a retry around the /health request allows the process to continue successfully, but it also forces us to wait for a potentially unnecessary amount of time before retrying.

Adding a sleep between PDF conversions does not appear to improve the situation.

Analysis

The issue appears to have been introduced in 8.29, since the same reproduction does not fail with 8.28 but does fail with versions up to 8.36.

The fact that retrying the /health request immediately succeeds makes me suspect a regression affecting the health check behavior under repeated conversion requests.

Do you know what might have changed in 8.29 that could explain this behavior? Is this a known issue?

Any feedback or insight would be greatly appreciated. Thank you very much for your help and for taking the time to look into this.

Activity

  1. gulien commented on Sep 3, 2026

    @gulien
    Member

    Confirmed regression, now fixed. Thanks for bisecting it to 8.28, that was the key detail.

    libreoffice-restart-after defaults to 10, so Gotenberg restarts LibreOffice in the background after every 10th conversion. In 8.28 a restarting process reported healthy; a refactor in 8.29 flipped that to unhealthy, so any /health probe landing in the restart window (roughly 150ms to 250ms) returned 503. Your conversions were never failing: requests arriving during a restart are requeued and served, not rejected. The burst of failures comes from the health library caching the DOWN result for 1s.

    Fixed in 88ddaed: planned restarts report healthy, crash-recovery restarts still report unhealthy. An integration test now reproduces your loop.

    Workaround until the next release: LIBREOFFICE_RESTART_AFTER=0.

    Please reopen if it persists after upgrading.

  2. adq-talbot commented on Sep 4, 2026

    @adq-talbot
    Author

    Thank you very much for the quick investigation and for fixing the regression!

  3. added a commit that references this issue on Sep 4, 2026
    88ddaed
  4. added a commit that references this issue on Oct 20, 2026
    73cf1e6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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