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)

Reply via email to