#18698·kestra

HTTP Request task: failed-response error log shows [0x36] instead of a line break in the response body

Author: sheikhmaamirCreated Aug 27, 2026Updated Sep 17, 2026
Labelsarea/plugingood first issue

Describe the issue

While testing how the io.kestra.plugin.core.http.Request task handles errors, I sent a request to a URL that returns a 404. The error log showed a strange token where a line break should be:

Failed http request with response code '404' and body:[0x36]{"message":"Not Found","documentation_url":"https://docs.github.com/rest/repos/repos#get-a-repository","status":"404"}

The [0x36] sits exactly where the newline between body: and the response should be. I checked the raw log via GET ``/api/v1/logs/{executionId} and the [0x36] is stored in the message itself, it's not just how the UI displays it.

Why (root cause)

Kestra builds this error message with a normal newline before the response body. The message is then passed through Apache HttpCore5's HttpException, whose clean() method is supposed to hex-escape control characters, but it has a bug: it generates the hex token from the character's position in the string instead of the character's value. So the newline (at position 54 in this message) becomes [0x36] (54 in hex) instead of a line break. I confirmed this by reading the Apache HttpCore5 source directly.

Kestra's own HttpClientException extends this Apache class, which is what exposes the bug to users on failed HTTP tasks.

Steps to reproduce:

id: repro_http_404
namespace: qa.repro
tasks:
  - id: request_404
    type: io.kestra.plugin.core.http.Request
    uri: https://api.github.com/repos/kestra-io/this-repo-does-not-exist-xyz
  1. Create and execute the flow.
  2. Open the execution's logs (UI, or GET /api/v1/logs/{executionId}).
  3. The error line shows [0x36] where a line break should be, before the response body.

Expected: The response body appears on a new line after body:, with a real line break.

Actual: The line break shows up as the literal token [0x36], and that token is stored in the log message itself (confirmed via GET /api/v1/logs/{executionId}), not just the UI. It's the newline's position (54) hex-escaped instead of its value — a bug in Apache HttpCore5's clean(), which Kestra's HttpClientException inherits.

Environment

  • Kestra: 1.3.35 OSS, commit c4e86ac (2026-08-25) via GET /api/v1/configs
  • Deployment: Docker (kestra/kestra:latest), running locally via docker run
  • Host: macOS 26.5.2 (build 25F84), arm64
  • Docker: 29.7.2