This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.22.x by this push:
     new bb264cbb676b [backport camel-4.22.x] CAMEL-26508: camel-netty - with 
transferExchange the consumer keeps its own connection headers (#29053)
bb264cbb676b is described below

commit bb264cbb676b24413f387dccd080130be90c3d9b
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Nov 4 09:20:24 2026 +0100

    [backport camel-4.22.x] CAMEL-26508: camel-netty - with transferExchange 
the consumer keeps its own connection headers (#29053)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../camel/catalog/components/netty-http.json       |   4 +-
 .../org/apache/camel/catalog/components/netty.json |   4 +-
 .../camel/component/netty/http/netty-http.json     |   4 +-
 .../org/apache/camel/component/netty/netty.json    |   4 +-
 .../camel/component/netty/NettyConfiguration.java  |  11 +-
 .../camel/component/netty/NettyPayloadHelper.java  |  53 ++++++-
 ...NettyTransferExchangeConnectionHeadersTest.java | 157 +++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc    |  10 ++
 .../dsl/NettyComponentBuilderFactory.java          |   8 +-
 .../dsl/NettyHttpComponentBuilderFactory.java      |   8 +-
 .../endpoint/dsl/NettyEndpointBuilderFactory.java  |  48 ++++++-
 .../dsl/NettyHttpEndpointBuilderFactory.java       |  48 ++++++-
 12 files changed, 331 insertions(+), 28 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty-http.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty-http.json
index 7961051ea48f..f3c5469436b8 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty-http.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty-http.json
@@ -77,7 +77,7 @@
     "receiveBufferSizePredictor": { "index": 49, "kind": "property", 
"displayName": "Receive Buffer Size Predictor", "group": "advanced", "label": 
"advanced", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Configures the buffer size predictor. See 
details at Jetty documentation and this mail [...]
     "sendBufferSize": { "index": 50, "kind": "property", "displayName": "Send 
Buffer Size", "group": "advanced", "label": "advanced", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 65536, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "The TCP\/UDP buffer sizes to be used during 
outbound communication. Size is bytes." },
     "shutdownTimeout": { "index": 51, "kind": "property", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Shutdown await timeout in milliseconds" },
-    "transferExchange": { "index": 52, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
+    "transferExchange": { "index": 52, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
     "udpByteArrayCodec": { "index": 53, "kind": "property", "displayName": 
"Udp Byte Array Codec", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.netty.NettyConfiguration", 
"configurationField": "configuration", "description": "For UDP only. If enabled 
the using byte array codec instead of Java serializa [...]
     "unixDomainSocketPath": { "index": 54, "kind": "property", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Path to unix domain socket to use instead of 
inet socket. Host and port parameters wil [...]
     "workerCount": { "index": 55, "kind": "property", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "When netty works on nio mode, it uses default 
workerCount parameter from Netty (which is cpu_core_threads x 2). User c [...]
@@ -200,7 +200,7 @@
     "shutdownTimeout": { "index": 65, "kind": "parameter", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Shutdown await timeout 
in milliseconds" },
     "synchronous": { "index": 66, "kind": "parameter", "displayName": 
"Synchronous", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Sets whether synchronous 
processing should be strictly used" },
     "transferException": { "index": 67, "kind": "parameter", "displayName": 
"Transfer Exception", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "If enabled and an 
Exchange fail [...]
-    "transferExchange": { "index": 68, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Only used for TCP. You 
can transf [...]
+    "transferExchange": { "index": 68, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Only used for TCP. You 
can transf [...]
     "unixDomainSocketPath": { "index": 69, "kind": "parameter", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Path to unix domain 
socket to use instead of inet socket. Host and port para [...]
     "workerCount": { "index": 70, "kind": "parameter", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "When netty works on nio 
mode, it uses default workerCount parameter from Netty (which is 
cpu_core_threads x  [...]
     "workerGroup": { "index": 71, "kind": "parameter", "displayName": "Worker 
Group", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "io.netty.channel.EventLoopGroup", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "To use a explicit 
EventLoopGroup as the boss thread pool. For example to share a  [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty.json
index 29c97da19505..77cb5c4988b9 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/netty.json
@@ -73,7 +73,7 @@
     "receiveBufferSizePredictor": { "index": 46, "kind": "property", 
"displayName": "Receive Buffer Size Predictor", "group": "advanced", "label": 
"advanced", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Configures the buffer size predictor. See 
details at Jetty documentation and this mail [...]
     "sendBufferSize": { "index": 47, "kind": "property", "displayName": "Send 
Buffer Size", "group": "advanced", "label": "advanced", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 65536, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "The TCP\/UDP buffer sizes to be used during 
outbound communication. Size is bytes." },
     "shutdownTimeout": { "index": 48, "kind": "property", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Shutdown await timeout in milliseconds" },
-    "transferExchange": { "index": 49, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
+    "transferExchange": { "index": 49, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
     "udpByteArrayCodec": { "index": 50, "kind": "property", "displayName": 
"Udp Byte Array Codec", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.netty.NettyConfiguration", 
"configurationField": "configuration", "description": "For UDP only. If enabled 
the using byte array codec instead of Java serializa [...]
     "unixDomainSocketPath": { "index": 51, "kind": "property", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Path to unix domain socket to use instead of 
inet socket. Host and port parameters wil [...]
     "workerCount": { "index": 52, "kind": "property", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "When netty works on nio mode, it uses default 
workerCount parameter from Netty (which is cpu_core_threads x 2). User c [...]
@@ -166,7 +166,7 @@
     "sendBufferSize": { "index": 48, "kind": "parameter", "displayName": "Send 
Buffer Size", "group": "advanced", "label": "advanced", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 65536, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "The TCP\/UDP buffer sizes to be used during 
outbound communication. Size is bytes." },
     "shutdownTimeout": { "index": 49, "kind": "parameter", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Shutdown await timeout in milliseconds" },
     "synchronous": { "index": 50, "kind": "parameter", "displayName": 
"Synchronous", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Sets whether 
synchronous processing should be strictly used" },
-    "transferExchange": { "index": 51, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the ex 
[...]
+    "transferExchange": { "index": 51, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the ex 
[...]
     "udpByteArrayCodec": { "index": 52, "kind": "parameter", "displayName": 
"Udp Byte Array Codec", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.netty.NettyConfiguration", 
"configurationField": "configuration", "description": "For UDP only. If enabled 
the using byte array codec instead of Java serializ [...]
     "unixDomainSocketPath": { "index": 53, "kind": "parameter", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Path to unix domain socket to use instead of 
inet socket. Host and port parameters wi [...]
     "workerCount": { "index": 54, "kind": "parameter", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "When netty works on nio mode, it uses default 
workerCount parameter from Netty (which is cpu_core_threads x 2). User  [...]
diff --git 
a/components/camel-netty-http/src/generated/resources/META-INF/org/apache/camel/component/netty/http/netty-http.json
 
b/components/camel-netty-http/src/generated/resources/META-INF/org/apache/camel/component/netty/http/netty-http.json
index 7961051ea48f..f3c5469436b8 100644
--- 
a/components/camel-netty-http/src/generated/resources/META-INF/org/apache/camel/component/netty/http/netty-http.json
+++ 
b/components/camel-netty-http/src/generated/resources/META-INF/org/apache/camel/component/netty/http/netty-http.json
@@ -77,7 +77,7 @@
     "receiveBufferSizePredictor": { "index": 49, "kind": "property", 
"displayName": "Receive Buffer Size Predictor", "group": "advanced", "label": 
"advanced", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Configures the buffer size predictor. See 
details at Jetty documentation and this mail [...]
     "sendBufferSize": { "index": 50, "kind": "property", "displayName": "Send 
Buffer Size", "group": "advanced", "label": "advanced", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 65536, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "The TCP\/UDP buffer sizes to be used during 
outbound communication. Size is bytes." },
     "shutdownTimeout": { "index": 51, "kind": "property", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Shutdown await timeout in milliseconds" },
-    "transferExchange": { "index": 52, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
+    "transferExchange": { "index": 52, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
     "udpByteArrayCodec": { "index": 53, "kind": "property", "displayName": 
"Udp Byte Array Codec", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.netty.NettyConfiguration", 
"configurationField": "configuration", "description": "For UDP only. If enabled 
the using byte array codec instead of Java serializa [...]
     "unixDomainSocketPath": { "index": 54, "kind": "property", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Path to unix domain socket to use instead of 
inet socket. Host and port parameters wil [...]
     "workerCount": { "index": 55, "kind": "property", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "When netty works on nio mode, it uses default 
workerCount parameter from Netty (which is cpu_core_threads x 2). User c [...]
@@ -200,7 +200,7 @@
     "shutdownTimeout": { "index": 65, "kind": "parameter", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Shutdown await timeout 
in milliseconds" },
     "synchronous": { "index": 66, "kind": "parameter", "displayName": 
"Synchronous", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Sets whether synchronous 
processing should be strictly used" },
     "transferException": { "index": 67, "kind": "parameter", "displayName": 
"Transfer Exception", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "If enabled and an 
Exchange fail [...]
-    "transferExchange": { "index": 68, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Only used for TCP. You 
can transf [...]
+    "transferExchange": { "index": 68, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Only used for TCP. You 
can transf [...]
     "unixDomainSocketPath": { "index": 69, "kind": "parameter", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "Path to unix domain 
socket to use instead of inet socket. Host and port para [...]
     "workerCount": { "index": 70, "kind": "parameter", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "When netty works on nio 
mode, it uses default workerCount parameter from Netty (which is 
cpu_core_threads x  [...]
     "workerGroup": { "index": 71, "kind": "parameter", "displayName": "Worker 
Group", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "io.netty.channel.EventLoopGroup", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.http.NettyHttpConfiguration", 
"configurationField": "configuration", "description": "To use a explicit 
EventLoopGroup as the boss thread pool. For example to share a  [...]
diff --git 
a/components/camel-netty/src/generated/resources/META-INF/org/apache/camel/component/netty/netty.json
 
b/components/camel-netty/src/generated/resources/META-INF/org/apache/camel/component/netty/netty.json
index 29c97da19505..77cb5c4988b9 100644
--- 
a/components/camel-netty/src/generated/resources/META-INF/org/apache/camel/component/netty/netty.json
+++ 
b/components/camel-netty/src/generated/resources/META-INF/org/apache/camel/component/netty/netty.json
@@ -73,7 +73,7 @@
     "receiveBufferSizePredictor": { "index": 46, "kind": "property", 
"displayName": "Receive Buffer Size Predictor", "group": "advanced", "label": 
"advanced", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Configures the buffer size predictor. See 
details at Jetty documentation and this mail [...]
     "sendBufferSize": { "index": 47, "kind": "property", "displayName": "Send 
Buffer Size", "group": "advanced", "label": "advanced", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 65536, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "The TCP\/UDP buffer sizes to be used during 
outbound communication. Size is bytes." },
     "shutdownTimeout": { "index": 48, "kind": "property", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Shutdown await timeout in milliseconds" },
-    "transferExchange": { "index": 49, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
+    "transferExchange": { "index": 49, "kind": "property", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the exc 
[...]
     "udpByteArrayCodec": { "index": 50, "kind": "property", "displayName": 
"Udp Byte Array Codec", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.netty.NettyConfiguration", 
"configurationField": "configuration", "description": "For UDP only. If enabled 
the using byte array codec instead of Java serializa [...]
     "unixDomainSocketPath": { "index": 51, "kind": "property", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Path to unix domain socket to use instead of 
inet socket. Host and port parameters wil [...]
     "workerCount": { "index": 52, "kind": "property", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "When netty works on nio mode, it uses default 
workerCount parameter from Netty (which is cpu_core_threads x 2). User c [...]
@@ -166,7 +166,7 @@
     "sendBufferSize": { "index": 48, "kind": "parameter", "displayName": "Send 
Buffer Size", "group": "advanced", "label": "advanced", "required": false, 
"type": "integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 65536, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "The TCP\/UDP buffer sizes to be used during 
outbound communication. Size is bytes." },
     "shutdownTimeout": { "index": 49, "kind": "parameter", "displayName": 
"Shutdown Timeout", "group": "advanced", "label": "advanced", "required": 
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": 100, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Shutdown await timeout in milliseconds" },
     "synchronous": { "index": 50, "kind": "parameter", "displayName": 
"Synchronous", "group": "advanced", "label": "advanced", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Sets whether 
synchronous processing should be strictly used" },
-    "transferExchange": { "index": 51, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the ex 
[...]
+    "transferExchange": { "index": 51, "kind": "parameter", "displayName": 
"Transfer Exchange", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "security": "insecure:serialization", 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Only used for TCP. You can transfer the ex 
[...]
     "udpByteArrayCodec": { "index": 52, "kind": "parameter", "displayName": 
"Udp Byte Array Codec", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.netty.NettyConfiguration", 
"configurationField": "configuration", "description": "For UDP only. If enabled 
the using byte array codec instead of Java serializ [...]
     "unixDomainSocketPath": { "index": 53, "kind": "parameter", "displayName": 
"Unix Domain Socket Path", "group": "advanced", "label": "advanced", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "Path to unix domain socket to use instead of 
inet socket. Host and port parameters wi [...]
     "workerCount": { "index": 54, "kind": "parameter", "displayName": "Worker 
Count", "group": "advanced", "label": "advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.netty.NettyConfiguration", "configurationField": 
"configuration", "description": "When netty works on nio mode, it uses default 
workerCount parameter from Netty (which is cpu_core_threads x 2). User  [...]
diff --git 
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
 
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
index 78a2cbd99f46..10b8290bcc72 100644
--- 
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
+++ 
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConfiguration.java
@@ -96,7 +96,11 @@ public class NettyConfiguration extends 
NettyServerBootstrapConfiguration implem
               description = "Only used for TCP. You can transfer the exchange 
over the wire instead of just the body. The following fields are"
                             + " transferred: In body, Out body, fault body, In 
headers, Out headers, fault headers, exchange properties, exchange"
                             + " exception. This requires that the objects are 
serializable. Camel will exclude any non-serializable objects and"
-                            + " log it at WARN level.")
+                            + " log it at WARN level. The connection headers 
(CamelNettyRemoteAddress, CamelNettyLocalAddress,"
+                            + " CamelNettyChannelHandlerContext, 
CamelNettySSLSession and the CamelNettySSLClientCert headers) and the"
+                            + " CamelNettyRemoteAddress and CamelNettyChannel 
exchange properties are always the ones of the receiving"
+                            + " side: the connection it accepted is the source 
of truth, and these values are never taken from the"
+                            + " transferred exchange.")
     private boolean transferExchange;
     @UriParam(label = "advanced", security = "insecure:serialization",
               description = "Only used for TCP when transferExchange is true. 
When set to true, serializable objects in headers and properties"
@@ -567,7 +571,10 @@ public class NettyConfiguration extends 
NettyServerBootstrapConfiguration implem
      * Only used for TCP. You can transfer the exchange over the wire instead 
of just the body. The following fields are
      * transferred: In body, Out body, fault body, In headers, Out headers, 
fault headers, exchange properties, exchange
      * exception. This requires that the objects are serializable. Camel will 
exclude any non-serializable objects and
-     * log it at WARN level.
+     * log it at WARN level. The connection headers (CamelNettyRemoteAddress, 
CamelNettyLocalAddress,
+     * CamelNettyChannelHandlerContext, CamelNettySSLSession and the 
CamelNettySSLClientCert headers) and the
+     * CamelNettyRemoteAddress and CamelNettyChannel exchange properties are 
always the ones of the receiving side: the
+     * connection it accepted is the source of truth, and these values are 
never taken from the transferred exchange.
      */
     public void setTransferExchange(boolean transferExchange) {
         this.transferExchange = transferExchange;
diff --git 
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyPayloadHelper.java
 
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyPayloadHelper.java
index d09c5d8ae4d5..5dfddf03c45d 100644
--- 
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyPayloadHelper.java
+++ 
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyPayloadHelper.java
@@ -17,6 +17,8 @@
 package org.apache.camel.component.netty;
 
 import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.AddressedEnvelope;
@@ -63,13 +65,13 @@ public final class NettyPayloadHelper {
 
     public static void setIn(Exchange exchange, Object payload) {
         if (payload instanceof DefaultExchangeHolder defaultExchangeHolder) {
-            DefaultExchangeHolder.unmarshal(exchange, defaultExchangeHolder);
+            unmarshal(exchange, defaultExchangeHolder);
         } else if (payload instanceof AddressedEnvelope) {
             @SuppressWarnings("unchecked")
             AddressedEnvelope<Object, InetSocketAddress> dp = 
(AddressedEnvelope<Object, InetSocketAddress>) payload;
             // need to check if the content is ExchangeHolder
             if (dp.content() instanceof DefaultExchangeHolder 
defaultExchangeHolder) {
-                DefaultExchangeHolder.unmarshal(exchange, 
defaultExchangeHolder);
+                unmarshal(exchange, defaultExchangeHolder);
             } else {
                 // need to take out the payload here
                 exchange.getIn().setBody(dp.content());
@@ -86,13 +88,13 @@ public final class NettyPayloadHelper {
 
     public static void setOut(Exchange exchange, Object payload) {
         if (payload instanceof DefaultExchangeHolder defaultExchangeHolder) {
-            DefaultExchangeHolder.unmarshal(exchange, defaultExchangeHolder);
+            unmarshal(exchange, defaultExchangeHolder);
         } else if (payload instanceof AddressedEnvelope) {
             @SuppressWarnings("unchecked")
             AddressedEnvelope<Object, InetSocketAddress> dp = 
(AddressedEnvelope<Object, InetSocketAddress>) payload;
             // need to check if the content is ExchangeHolder
             if (dp.content() instanceof DefaultExchangeHolder 
defaultExchangeHolder) {
-                DefaultExchangeHolder.unmarshal(exchange, 
defaultExchangeHolder);
+                unmarshal(exchange, defaultExchangeHolder);
             } else {
                 // need to take out the payload here
                 exchange.getOut().setBody(dp.content());
@@ -106,4 +108,47 @@ public final class NettyPayloadHelper {
         }
     }
 
+    /**
+     * The headers and exchange properties that describe the Netty connection 
of this side.
+     */
+    private static final String[] CONNECTION_KEYS = {
+            NettyConstants.NETTY_CHANNEL_HANDLER_CONTEXT, 
NettyConstants.NETTY_REMOTE_ADDRESS,
+            NettyConstants.NETTY_LOCAL_ADDRESS, NettyConstants.NETTY_CHANNEL,
+            NettyConstants.NETTY_SSL_SESSION, 
NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME,
+            NettyConstants.NETTY_SSL_CLIENT_CERT_ISSUER_NAME, 
NettyConstants.NETTY_SSL_CLIENT_CERT_SERIAL_NO,
+            NettyConstants.NETTY_SSL_CLIENT_CERT_NOT_BEFORE, 
NettyConstants.NETTY_SSL_CLIENT_CERT_NOT_AFTER };
+
+    /**
+     * Unmarshals the transferred exchange into the exchange, but keeps the 
connection headers and exchange properties
+     * of this side: the connection this side accepted (or opened) is the 
source of truth for them. A connection header
+     * or property in the transferred exchange is never used, also when this 
side has no value for it (for example the
+     * SSL client certificate headers when the connection has no client 
certificate).
+     */
+    private static void unmarshal(Exchange exchange, DefaultExchangeHolder 
holder) {
+        Map<String, Object> headers = new HashMap<>();
+        Map<String, Object> properties = new HashMap<>();
+        for (String key : CONNECTION_KEYS) {
+            Object value = exchange.getIn().getHeader(key);
+            if (value != null) {
+                headers.put(key, value);
+            }
+            value = exchange.getProperty(key);
+            if (value != null) {
+                properties.put(key, value);
+            }
+        }
+
+        DefaultExchangeHolder.unmarshal(exchange, holder);
+
+        for (String key : CONNECTION_KEYS) {
+            exchange.getIn().removeHeader(key);
+            if (exchange.hasOut()) {
+                exchange.getOut().removeHeader(key);
+            }
+            exchange.removeProperty(key);
+        }
+        headers.forEach(exchange.getIn()::setHeader);
+        properties.forEach(exchange::setProperty);
+    }
+
 }
diff --git 
a/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTransferExchangeConnectionHeadersTest.java
 
b/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTransferExchangeConnectionHeadersTest.java
new file mode 100644
index 000000000000..360185c2913f
--- /dev/null
+++ 
b/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyTransferExchangeConnectionHeadersTest.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.netty;
+
+import java.io.File;
+import java.net.InetSocketAddress;
+
+import io.netty.channel.ChannelHandler;
+import io.netty.handler.codec.serialization.ClassResolvers;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.netty.codec.ObjectDecoder;
+import org.apache.camel.component.netty.codec.ObjectEncoder;
+import org.apache.camel.test.AvailablePortFinder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * With transferExchange the consumer keeps its own connection headers: the 
connection it accepted is the source of
+ * truth, so the connection headers and properties in the transferred exchange 
are not used.
+ */
+@DisabledIfSystemProperty(named = "java.vendor", matches = ".*ibm.*")
+public class NettyTransferExchangeConnectionHeadersTest extends BaseNettyTest {
+
+    private static final String CLIENT_CERT_SUBJECT
+            = "SERIALNUMBER=1234567890, CN=CommonName, OU=Unit, O=Org, L=Loc, 
ST=State, C=US";
+    private static final String CODECS = 
"&encoders=#encoder&decoders=#decoder";
+    private static final String SSL_OPTIONS = 
"&ssl=true&passphrase=changeit&keyStoreResource=#ksf&trustStoreResource=#tsf";
+
+    @RegisterExtension
+    AvailablePortFinder.Port sslPort = AvailablePortFinder.find();
+
+    @BindToRegistry("ksf")
+    public File loadKeystoreKsf() {
+        return new File("src/test/resources/keystore.jks");
+    }
+
+    @BindToRegistry("tsf")
+    public File loadKeystoreTsf() {
+        return new File("src/test/resources/keystore.jks");
+    }
+
+    @BindToRegistry("encoder")
+    public ChannelHandler getEncoder() {
+        return new ShareableChannelHandlerFactory(new ObjectEncoder());
+    }
+
+    @BindToRegistry("decoder")
+    public ChannelHandler getDecoder() {
+        return new DefaultChannelHandlerFactory() {
+            @Override
+            public ChannelHandler newChannelHandler() {
+                return new 
ObjectDecoder(ClassResolvers.weakCachingResolver(null));
+            }
+        };
+    }
+
+    @Test
+    public void testConsumerKeepsItsConnectionHeaders() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:plain");
+        mock.expectedBodiesReceived("Hello World");
+        mock.expectedHeaderReceived("cheese", "gouda");
+
+        Exchange reply = 
template.request("netty:tcp://localhost:{{port}}?sync=true&transferExchange=true"
 + CODECS, e -> {
+            e.getIn().setBody("Hello World");
+            e.getIn().setHeader("cheese", "gouda");
+            e.getIn().setHeader(NettyConstants.NETTY_REMOTE_ADDRESS, 
"10.1.2.3:4567");
+            e.getIn().setHeader(NettyConstants.NETTY_LOCAL_ADDRESS, 
"10.1.2.3:8910");
+            
e.getIn().setHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME, 
"CN=Sender");
+            
e.getIn().setHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SERIAL_NO, "42");
+            e.setProperty(NettyConstants.NETTY_REMOTE_ADDRESS, 
"10.1.2.3:4567");
+        });
+        assertNull(reply.getException());
+
+        MockEndpoint.assertIsSatisfied(context);
+
+        Exchange received = mock.getReceivedExchanges().get(0);
+        Message in = received.getIn();
+        // the addresses of the connection the consumer accepted
+        assertInstanceOf(InetSocketAddress.class, 
in.getHeader(NettyConstants.NETTY_REMOTE_ADDRESS));
+        InetSocketAddress local = assertInstanceOf(InetSocketAddress.class, 
in.getHeader(NettyConstants.NETTY_LOCAL_ADDRESS));
+        assertEquals(getPort(), local.getPort());
+        // no client certificate on this connection, so no client certificate 
headers
+        
assertNull(in.getHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME));
+        
assertNull(in.getHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SERIAL_NO));
+        assertNull(received.getProperty(NettyConstants.NETTY_REMOTE_ADDRESS));
+
+        // the producer keeps its own connection headers too: the reply has 
none from the consumer
+        Message message = reply.getMessage();
+        assertEquals("Bye World", message.getBody());
+        assertEquals("cheddar", message.getHeader("cheese"));
+        
assertNull(message.getHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME));
+        assertNull(message.getHeader(NettyConstants.NETTY_REMOTE_ADDRESS));
+    }
+
+    @Test
+    public void testConsumerKeepsItsClientCertHeaders() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:ssl");
+        mock.expectedBodiesReceived("Hello World");
+        
mock.expectedHeaderReceived(NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME, 
CLIENT_CERT_SUBJECT);
+        
mock.expectedHeaderReceived(NettyConstants.NETTY_SSL_CLIENT_CERT_ISSUER_NAME, 
CLIENT_CERT_SUBJECT);
+        
mock.expectedHeaderReceived(NettyConstants.NETTY_SSL_CLIENT_CERT_SERIAL_NO, 
"1234567890");
+
+        Exchange reply = template.request(
+                "netty:tcp://localhost:" + sslPort.getPort() + 
"?sync=true&transferExchange=true" + CODECS + SSL_OPTIONS, e -> {
+                    e.getIn().setBody("Hello World");
+                    
e.getIn().setHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME, 
"CN=Sender");
+                    
e.getIn().setHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_ISSUER_NAME, 
"CN=Sender CA");
+                    
e.getIn().setHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SERIAL_NO, "42");
+                });
+        assertNull(reply.getException());
+        assertEquals("Bye World", reply.getMessage().getBody());
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                
from("netty:tcp://localhost:{{port}}?sync=true&transferExchange=true" + CODECS)
+                        .to("mock:plain")
+                        .setHeader("cheese", constant("cheddar"))
+                        
.setHeader(NettyConstants.NETTY_SSL_CLIENT_CERT_SUBJECT_NAME, 
constant("CN=Consumer"))
+                        .transform().constant("Bye World");
+
+                from("netty:tcp://localhost:" + sslPort.getPort() + 
"?sync=true&transferExchange=true" + CODECS + SSL_OPTIONS
+                     + "&needClientAuth=true&sslClientCertHeaders=true")
+                        .to("mock:ssl")
+                        .transform().constant("Bye World");
+            }
+        };
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
index 1c2b25546979..780d9f5fdb33 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
@@ -163,6 +163,16 @@ credentials. A deployment that counted on the inherited 
list as a restriction ha
 A consumer whose `requestUriPattern` is `/` now also uses its own keys, 
certificates and asynchronous MDN settings when
 another consumer created the shared server connection; before, it used the 
first consumer's.
 
+=== camel-netty - with transferExchange the consumer keeps its own connection 
headers
+
+With `transferExchange=true` the connection headers `CamelNettyRemoteAddress`, 
`CamelNettyLocalAddress`,
+`CamelNettyChannelHandlerContext`, `CamelNettySSLSession` and the 
`CamelNettySSLClientCert*` headers (and the
+`CamelNettyRemoteAddress` and `CamelNettyChannel` exchange properties) are now 
always the ones of the receiving side:
+the connection it accepted is the source of truth. Before, the headers of the 
transferred exchange replaced them. Such
+a header in the transferred exchange is no longer used, also when the 
receiving side has no value for it (for example
+the `CamelNettySSLClientCert*` headers on a connection without a client 
certificate). This also applies to the reply
+the producer receives. Send any such value of the sender under a header name 
of your own.
+
 == Upgrading from 4.22.1 to 4.22.2
 
 === camel-management - Route group exchange counters count once per entry into 
the group again
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyComponentBuilderFactory.java
index e10919a8a683..8a2ee3d37965 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyComponentBuilderFactory.java
@@ -994,7 +994,13 @@ public interface NettyComponentBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyHttpComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyHttpComponentBuilderFactory.java
index d8036cb42c42..719419f6e9ef 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyHttpComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/NettyHttpComponentBuilderFactory.java
@@ -1048,7 +1048,13 @@ public interface NettyHttpComponentBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyEndpointBuilderFactory.java
index b221fedb2319..d962147a03f7 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyEndpointBuilderFactory.java
@@ -1653,7 +1653,13 @@ public interface NettyEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: <code>boolean</code> type.
          * 
@@ -1673,7 +1679,13 @@ public interface NettyEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option will be converted to a <code>boolean</code> type.
          * 
@@ -3373,7 +3385,13 @@ public interface NettyEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: <code>boolean</code> type.
          * 
@@ -3393,7 +3411,13 @@ public interface NettyEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option will be converted to a <code>boolean</code> type.
          * 
@@ -4543,7 +4567,13 @@ public interface NettyEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: <code>boolean</code> type.
          * 
@@ -4563,7 +4593,13 @@ public interface NettyEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option will be converted to a <code>boolean</code> type.
          * 
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyHttpEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyHttpEndpointBuilderFactory.java
index 69e1832d3666..ed681904f616 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyHttpEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/NettyHttpEndpointBuilderFactory.java
@@ -2136,7 +2136,13 @@ public interface NettyHttpEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: <code>boolean</code> type.
          * 
@@ -2156,7 +2162,13 @@ public interface NettyHttpEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option will be converted to a <code>boolean</code> type.
          * 
@@ -3887,7 +3899,13 @@ public interface NettyHttpEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: <code>boolean</code> type.
          * 
@@ -3907,7 +3925,13 @@ public interface NettyHttpEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option will be converted to a <code>boolean</code> type.
          * 
@@ -5096,7 +5120,13 @@ public interface NettyHttpEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option is a: <code>boolean</code> type.
          * 
@@ -5116,7 +5146,13 @@ public interface NettyHttpEndpointBuilderFactory {
          * body, Out body, fault body, In headers, Out headers, fault headers,
          * exchange properties, exchange exception. This requires that the
          * objects are serializable. Camel will exclude any non-serializable
-         * objects and log it at WARN level.
+         * objects and log it at WARN level. The connection headers
+         * (CamelNettyRemoteAddress, CamelNettyLocalAddress,
+         * CamelNettyChannelHandlerContext, CamelNettySSLSession and the
+         * CamelNettySSLClientCert headers) and the CamelNettyRemoteAddress and
+         * CamelNettyChannel exchange properties are always the ones of the
+         * receiving side: the connection it accepted is the source of truth,
+         * and these values are never taken from the transferred exchange.
          * 
          * The option will be converted to a <code>boolean</code> type.
          * 

Reply via email to