shashank created CAMEL-25277:
--------------------------------
Summary: camel-nats - a request to an InOut consumer whose route
fails gets a successful reply with the body of the failed exchange (usually its
own request)
Key: CAMEL-25277
URL: https://issues.apache.org/jira/browse/CAMEL-25277
Project: Camel
Issue Type: Bug
Components: camel-nats
Reporter: shashank
The NATS consumer answers a message that has a reply subject (a request) with
the body of the exchange once the route has run, when the exchange pattern is
InOut (CAMEL-23676). It does not look at the result of the exchange: when the
route fails, the requester gets the body of the failed exchange as a successful
reply. That body is usually the request itself, or whatever the route had set
before it failed. A requester (for example a Camel route with
{{to("nats:subject")}} as InOut, or any NATS client with {{request()}}) then
goes on with a wrong answer and never learns that the request failed.
NATS has no error reply. The other broker request/reply consumers send no reply
in the same situation, so the requester times out: camel-jms and camel-sjms
(without {{transferException}}) and camel-spring-rabbitmq, all three also for
an exchange marked rollback only. (A reply with an error header, such as the
{{Nats-Service-Error}} headers of the NATS service API, would not help a
generic requester or the camel-nats producer, which would take it as a
successful empty reply; replying with the exception message would send the
route's exception to the requester.)
h3. Reproduction
{{NatsConsumerReplyToFailureIT}}: a route
{{from("nats:failing?exchangePattern=InOut").throwException(new
IllegalArgumentException("Forced"))}} and a request
{{template.requestBody("nats:failing?requestTimeout=1000", "World")}}. On main
the request returns {{"World"}} (its own body) instead of failing. Run against
a local nats-server 2.15.0 (the module's ITs use a NATS container; with
{{-Dnats.instance.type=remote}} the test-infra still requires Docker, so the
run used a local server and a temporary, uncommitted change to
{{NatsITSupport}}).
h3. Proposed fix
Do not reply when the exchange failed or is marked rollback only. The requester
times out ({{ExchangeTimedOutException}} after {{requestTimeout}} with the
camel-nats producer). A failure that the route handles
({{onException(...).handled(true)}}) is not a failed exchange and is answered
as before. The exception message is not sent to the requester (security model:
a consumer must not return the route's exception to the sender).
With the fix the new IT (2 tests: no reply for a failed exchange, and a reply
for a handled failure) passes; the module's unit tests (5) and the 26 ITs that
use {{NatsITSupport}} (core and JetStream) pass against the local server; the 4
auth ITs need their own containers and were skipped. The upgrade guide gets a
note.
Affected: 4.14.x and 4.18.x (there the consumer replies whatever the exchange
pattern), 4.22.x and main.
Duplicate check (2026-10-02): JIRA component camel-nats (last 3 years, 13
issues) and text "nats" with "reply" (4 issues): CAMEL-23676 (reply only for
InOut), CAMEL-14252, CAMEL-9885, CAMEL-21749; none about failures. GitHub pull
requests: only #23739 (CAMEL-23676) changed the reply.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)