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

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


The following commit(s) were added to refs/heads/main by this push:
     new 2f05680c9562 CAMEL-25462: camel-platform-http-main - management 
settings ignored on a shared server port (#28175)
2f05680c9562 is described below

commit 2f05680c95628806af7040fc2c5acf52c106a1d1
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Oct 20 21:01:08 2026 +0200

    CAMEL-25462: camel-platform-http-main - management settings ignored on a 
shared server port (#28175)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/camel/catalog/docs/main.adoc        |   2 +-
 .../camel/catalog/docs/platform-http-main.adoc     |  22 +++
 .../main/camel-main-configuration-metadata.json    |   2 +-
 .../src/main/docs/platform-http-main.adoc          |  22 +++
 .../platform/http/main/ManagementHttpServer.java   |  38 +++++
 .../main/ManagementHttpServerSharedPortTest.java   | 185 +++++++++++++++++++++
 .../camel-main-configuration-metadata.json         |   2 +-
 core/camel-main/src/main/docs/main.adoc            |   2 +-
 ...ttpManagementServerConfigurationProperties.java |   8 +
 .../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc    |  16 ++
 .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc    |  16 ++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  16 ++
 .../java/org/apache/camel/main/KameletMain.java    |  36 +++-
 .../main/KameletMainMcpManagementHostTest.java     |  77 +++++++++
 .../apache/camel/main/mcp-shared-port.properties   |  19 +++
 15 files changed, 456 insertions(+), 7 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/main.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/main.adoc
index 75306c4f9e1f..884a26ccd412 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/main.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/main.adoc
@@ -272,7 +272,7 @@ The camel.management supports 31 options, which are listed 
below.
 | `camel.management.openapiUiEnabled` | Whether to enable Swagger UI for REST 
DSL OpenAPI documents. If enabled then you can browse the API at context-path: 
/q/openapi. The OpenAPI document is expected at openapiUiSpecPath (by default 
/q/openapi.json from REST DSL apiContextPath ). | false | boolean
 | `camel.management.openapiUiSpecPath` | Path or URL of the OpenAPI document 
loaded by Swagger UI at /q/openapi. | /q/openapi.json | String
 | `camel.management.path` | Context-path to use for embedded HTTP server | / | 
String
-| `camel.management.port` | Port to use for binding embedded HTTP management 
server. Use 0 to dynamic assign a free random port number. | 8080 | int
+| `camel.management.port` | Port to use for binding embedded HTTP management 
server. Use 0 to dynamic assign a free random port number. When the embedded 
HTTP server is enabled with the same port (both default to 8080), the 
management endpoints are served by the HTTP server, which cannot apply a host, 
path, SSL or authentication of the management server's own. The management 
server then fails to start when such a setting is configured. Use a different 
port to apply it. | 8080 | int
 | `camel.management.sendEnabled` | Whether to enable sending messages to Camel 
via HTTP. This makes it possible to use Camel to send messages to Camel 
endpoint URIs via HTTP. | false | boolean
 | `camel.management.uploadEnabled` | Whether to enable file upload via HTTP 
(not intended for production use). This functionality is for development to be 
able to reload Camel routes and code with source changes (if reload is 
enabled). If enabled then you can upload/delete files via HTTP PUT/DELETE on 
context-path: /q/upload/\{name}. You must also configure the uploadSourceDir 
option. | false | boolean
 | `camel.management.uploadSourceDir` | Source directory when upload is 
enabled. |  | String
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-main.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-main.adoc
index bf00766a9894..45827b5a56ce 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-main.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/platform-http-main.adoc
@@ -80,6 +80,28 @@ A file on the classpath can be downloaded even if it is not 
listed (when not usi
 curl http://localhost:8080/q/download/application.properties
 ----
 
+== Sharing the port with the management server
+
+The management features (`/observe/...` and `/q/...`) are served by the HTTP 
management server (`camel.management.enabled=true`).
+When the HTTP server is enabled as well and both have the same port 
(`camel.server.port` and `camel.management.port` both default to 8080),
+the management server does not start a server of its own. The HTTP server 
serves the management endpoints instead, with its own host, path,
+SSL and authentication. For example, authentication configured on the HTTP 
server for `/*` applies to the management endpoints too.
+
+The HTTP server cannot apply the host, path, SSL 
(`useGlobalSslContextParameters`) or authentication options of the management 
server.
+Camel therefore fails to start when the management server shares the port and 
one of them is configured
+(a host or path equal to the one of the HTTP server is accepted). Give the 
management server a port of its own to apply them:
+
+[source,properties]
+----
+camel.server.enabled=true
+camel.server.port=8080
+
+camel.management.enabled=true
+camel.management.port=8081
+camel.management.host=127.0.0.1
+camel.management.healthCheckEnabled=true
+----
+
 == JWT authentication
 
 The embedded HTTP server can validate JWT bearer tokens on incoming requests.
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index ddd3fcbbdbe8..86cd31e2a938 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -323,7 +323,7 @@
     { "name": "camel.management.openapiUiEnabled", "required": false, 
"description": "Whether to enable Swagger UI for REST DSL OpenAPI documents. If 
enabled then you can browse the API at context-path: \/q\/openapi. The OpenAPI 
document is expected at openapiUiSpecPath (by default \/q\/openapi.json from 
REST DSL apiContextPath ).", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"boolean", "javaType": "boolean", "defaultValue": false, "secret": [...]
     { "name": "camel.management.openapiUiSpecPath", "required": false, 
"description": "Path or URL of the OpenAPI document loaded by Swagger UI at 
\/q\/openapi.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "defaultValue": "\/q\/openapi.json", 
"secret": false },
     { "name": "camel.management.path", "required": false, "description": 
"Context-path to use for embedded HTTP server", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "defaultValue": "\/", "secret": false 
},
-    { "name": "camel.management.port", "required": false, "description": "Port 
to use for binding embedded HTTP management server. Use 0 to dynamic assign a 
free random port number.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"integer", "javaType": "int", "defaultValue": 8080, "secret": false },
+    { "name": "camel.management.port", "required": false, "description": "Port 
to use for binding embedded HTTP management server. Use 0 to dynamic assign a 
free random port number. When the embedded HTTP server is enabled with the same 
port (both default to 8080), the management endpoints are served by the HTTP 
server, which cannot apply a host, path, SSL or authentication of the 
management server's own. The management server then fails to start when such a 
setting is configured. Use a  [...]
     { "name": "camel.management.sendEnabled", "required": false, 
"description": "Whether to enable sending messages to Camel via HTTP. This 
makes it possible to use Camel to send messages to Camel endpoint URIs via 
HTTP.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"boolean", "javaType": "boolean", "defaultValue": false, "secret": false, 
"security": "insecure:dev" },
     { "name": "camel.management.uploadEnabled", "required": false, 
"description": "Whether to enable file upload via HTTP (not intended for 
production use). This functionality is for development to be able to reload 
Camel routes and code with source changes (if reload is enabled). If enabled 
then you can upload\/delete files via HTTP PUT\/DELETE on context-path: 
\/q\/upload\/{name}. You must also configure the uploadSourceDir option.", 
"sourceType": "org.apache.camel.main.HttpManagementS [...]
     { "name": "camel.management.uploadSourceDir", "required": false, 
"description": "Source directory when upload is enabled.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "secret": false },
diff --git 
a/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc 
b/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc
index bf00766a9894..45827b5a56ce 100644
--- a/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc
+++ b/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc
@@ -80,6 +80,28 @@ A file on the classpath can be downloaded even if it is not 
listed (when not usi
 curl http://localhost:8080/q/download/application.properties
 ----
 
+== Sharing the port with the management server
+
+The management features (`/observe/...` and `/q/...`) are served by the HTTP 
management server (`camel.management.enabled=true`).
+When the HTTP server is enabled as well and both have the same port 
(`camel.server.port` and `camel.management.port` both default to 8080),
+the management server does not start a server of its own. The HTTP server 
serves the management endpoints instead, with its own host, path,
+SSL and authentication. For example, authentication configured on the HTTP 
server for `/*` applies to the management endpoints too.
+
+The HTTP server cannot apply the host, path, SSL 
(`useGlobalSslContextParameters`) or authentication options of the management 
server.
+Camel therefore fails to start when the management server shares the port and 
one of them is configured
+(a host or path equal to the one of the HTTP server is accepted). Give the 
management server a port of its own to apply them:
+
+[source,properties]
+----
+camel.server.enabled=true
+camel.server.port=8080
+
+camel.management.enabled=true
+camel.management.port=8081
+camel.management.host=127.0.0.1
+camel.management.healthCheckEnabled=true
+----
+
 == JWT authentication
 
 The embedded HTTP server can validate JWT bearer tokens on incoming requests.
diff --git 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
index c648a8ccc4ad..1f0b9381fb78 100644
--- 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
+++ 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/ManagementHttpServer.java
@@ -38,6 +38,7 @@ import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.StringJoiner;
 import java.util.TreeSet;
@@ -432,6 +433,7 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         VertxPlatformHttpServer mainServer = 
camelContext.hasService(VertxPlatformHttpServer.class);
         if (mainServer != null && mainServer.getConfigurationPort() == 
configuration.getPort()) {
             // reuse main server as we should use same port
+            checkSettingsApplyOnSharedServer(mainServer);
             server = mainServer;
         } else {
             server = new VertxPlatformHttpServer(configuration);
@@ -448,6 +450,42 @@ public class ManagementHttpServer extends ServiceSupport 
implements CamelContext
         ServiceHelper.initService(pluginRegistry);
     }
 
+    /**
+     * On a shared port the management endpoints are added to the main server, 
which keeps its own host, path, SSL and
+     * authentication. Fail instead of ignoring the management server settings 
it cannot apply.
+     */
+    private void checkSettingsApplyOnSharedServer(VertxPlatformHttpServer 
mainServer) {
+        List<String> ignored = new ArrayList<>();
+        String host = configuration.getBindHost();
+        if 
(!VertxPlatformHttpServerConfiguration.DEFAULT_BIND_HOST.equals(host)
+                && !Objects.equals(host, mainServer.getHost())) {
+            ignored.add("camel.management.host=" + host + " (the HTTP server 
binds to " + mainServer.getHost() + ")");
+        }
+        String path = configuration.getPath();
+        if (!VertxPlatformHttpServerConfiguration.DEFAULT_PATH.equals(path)
+                && !Objects.equals(path, mainServer.getPath())) {
+            ignored.add("camel.management.path=" + path + " (the HTTP server 
uses " + mainServer.getPath() + ")");
+        }
+        if (configuration.getSslContextParameters() != null) {
+            ignored.add("sslContextParameters (the HTTP server uses its own 
SSL configuration)");
+        } else if (configuration.isUseGlobalSslContextParameters() && 
!mainServer.isUseGlobalSslContextParameters()) {
+            ignored.add("camel.management.useGlobalSslContextParameters=true 
(the HTTP server does not use the global SSL"
+                        + " configuration)");
+        }
+        if (configuration.getAuthenticationConfig().isEnabled()) {
+            ignored.add("authentication 
(camel.management.authenticationEnabled)");
+        }
+        if (!ignored.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "The HTTP management server uses the same port " + 
configuration.getPort()
+                                               + " as the HTTP server, which 
serves the management endpoints but cannot apply"
+                                               + " these management server 
settings: " + String.join(", ", ignored)
+                                               + ". Set camel.management.port 
to another port so that the management server"
+                                               + " applies them, or remove 
them and configure the HTTP server (camel.server.*)"
+                                               + " instead.");
+        }
+    }
+
     @Override
     protected void doStart() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext");
diff --git 
a/components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/ManagementHttpServerSharedPortTest.java
 
b/components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/ManagementHttpServerSharedPortTest.java
new file mode 100644
index 000000000000..803d9dd4ab94
--- /dev/null
+++ 
b/components/camel-platform-http-main/src/test/java/org/apache/camel/component/platform/http/main/ManagementHttpServerSharedPortTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.platform.http.main;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpServer;
+import 
org.apache.camel.component.platform.http.vertx.VertxPlatformHttpServerConfiguration;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.main.Main;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.test.AvailablePortFinder;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The management server shares the HTTP server when both have the same port, 
and the HTTP server then serves the
+ * management endpoints with its own host, path, SSL and authentication.
+ */
+class ManagementHttpServerSharedPortTest {
+
+    @RegisterExtension
+    AvailablePortFinder.Port port = AvailablePortFinder.find();
+
+    @RegisterExtension
+    AvailablePortFinder.Port managementPort = AvailablePortFinder.find();
+
+    private Main main;
+
+    @AfterEach
+    void stopMain() {
+        if (main != null) {
+            main.stop();
+        }
+    }
+
+    @Test
+    void sharedPortServesManagementEndpointsOnTheHttpServer() throws Exception 
{
+        createMain().start();
+
+        assertEquals(200, get("localhost", port.getPort(), "/observe/info", 
null).statusCode());
+    }
+
+    @Test
+    void sharedPortAcceptsTheHostAndPathOfTheHttpServer() throws Exception {
+        createMain("camel.server.host", "127.0.0.1", "camel.management.host", 
"127.0.0.1",
+                "camel.server.path", "/app", "camel.management.path", 
"/app").start();
+
+        assertEquals(200, get("127.0.0.1", port.getPort(), 
"/app/observe/info", null).statusCode());
+    }
+
+    @Test
+    void sharedPortAppliesTheAuthenticationOfTheHttpServer() throws Exception {
+        createMain("camel.server.authenticationEnabled", "true", 
"camel.server.authenticationPath", "/*",
+                "camel.server.basicPropertiesFile", 
"camel-platform-http-vertx-auth.properties").start();
+
+        assertEquals(401, get("localhost", port.getPort(), "/observe/info", 
null).statusCode());
+        assertEquals(200, get("localhost", port.getPort(), "/observe/info", 
"camel:propertiesPass").statusCode());
+    }
+
+    @Test
+    void sharedPortRejectsAnotherManagementHost() {
+        createMain("camel.management.host", "127.0.0.1");
+
+        String message = startFailure();
+        assertTrue(message.contains("camel.management.host=127.0.0.1"), 
message);
+        assertTrue(message.contains("camel.management.port"), message);
+    }
+
+    @Test
+    void sharedPortRejectsAnotherManagementPath() {
+        createMain("camel.management.path", "/management");
+
+        String message = startFailure();
+        assertTrue(message.contains("camel.management.path=/management"), 
message);
+    }
+
+    @Test
+    void sharedPortRejectsManagementGlobalSsl() {
+        createMain("camel.management.useGlobalSslContextParameters", "true");
+
+        String message = startFailure();
+        
assertTrue(message.contains("camel.management.useGlobalSslContextParameters=true"),
 message);
+    }
+
+    @Test
+    void sharedPortRejectsManagementAuthentication() {
+        createMain("camel.management.authenticationEnabled", "true",
+                "camel.management.basicPropertiesFile", 
"camel-platform-http-vertx-auth.properties");
+
+        String message = startFailure();
+        assertTrue(message.contains("camel.management.authenticationEnabled"), 
message);
+    }
+
+    @Test
+    void sharedPortRejectsManagementSslContextParameters() throws Exception {
+        // only set programmatically: camel-main has no option for it
+        try (CamelContext context = new DefaultCamelContext()) {
+            VertxPlatformHttpServerConfiguration configuration = new 
VertxPlatformHttpServerConfiguration();
+            configuration.setBindPort(port.getPort());
+            context.addService(new VertxPlatformHttpServer(configuration));
+
+            ManagementHttpServer server = new ManagementHttpServer();
+            server.setCamelContext(context);
+            server.setPort(port.getPort());
+            server.setSslContextParameters(new SSLContextParameters());
+
+            IllegalArgumentException e = 
assertThrows(IllegalArgumentException.class, server::init);
+            assertTrue(e.getMessage().contains("sslContextParameters (the HTTP 
server uses its own SSL configuration)"),
+                    e.getMessage());
+        }
+    }
+
+    @Test
+    void ownPortAppliesTheManagementSettings() throws Exception {
+        createMain("camel.management.port", 
Integer.toString(managementPort.getPort()),
+                "camel.management.host", "127.0.0.1", "camel.management.path", 
"/management",
+                "camel.management.authenticationEnabled", "true",
+                "camel.management.basicPropertiesFile", 
"camel-platform-http-vertx-auth.properties").start();
+
+        assertEquals(401, get("127.0.0.1", managementPort.getPort(), 
"/management/observe/info", null).statusCode());
+        assertEquals(200,
+                get("127.0.0.1", managementPort.getPort(), 
"/management/observe/info", "camel:propertiesPass")
+                        .statusCode());
+        assertEquals(404, get("localhost", port.getPort(), "/observe/info", 
null).statusCode());
+    }
+
+    private Main createMain(String... properties) {
+        main = new Main();
+        main.addOverrideProperty("camel.server.enabled", "true");
+        main.addOverrideProperty("camel.server.port", 
Integer.toString(port.getPort()));
+        main.addOverrideProperty("camel.management.enabled", "true");
+        main.addOverrideProperty("camel.management.port", 
Integer.toString(port.getPort()));
+        main.addOverrideProperty("camel.management.infoEnabled", "true");
+        for (int i = 0; i < properties.length; i += 2) {
+            main.addOverrideProperty(properties[i], properties[i + 1]);
+        }
+        return main;
+    }
+
+    private String startFailure() {
+        Exception e = assertThrows(Exception.class, main::start);
+        Throwable cause = e;
+        while (cause != null && !(cause instanceof IllegalArgumentException)) {
+            cause = cause.getCause();
+        }
+        assertNotNull(cause, "Expected an IllegalArgumentException, got: " + 
e);
+        return cause.getMessage();
+    }
+
+    private static HttpResponse<String> get(String host, int port, String 
path, String credentials) throws Exception {
+        HttpRequest.Builder request = 
HttpRequest.newBuilder().uri(URI.create("http://"; + host + ":" + port + path));
+        if (credentials != null) {
+            request.header("Authorization",
+                    "Basic " + 
Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8)));
+        }
+        return HttpClient.newHttpClient().send(request.build(), 
HttpResponse.BodyHandlers.ofString());
+    }
+}
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index ddd3fcbbdbe8..86cd31e2a938 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -323,7 +323,7 @@
     { "name": "camel.management.openapiUiEnabled", "required": false, 
"description": "Whether to enable Swagger UI for REST DSL OpenAPI documents. If 
enabled then you can browse the API at context-path: \/q\/openapi. The OpenAPI 
document is expected at openapiUiSpecPath (by default \/q\/openapi.json from 
REST DSL apiContextPath ).", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"boolean", "javaType": "boolean", "defaultValue": false, "secret": [...]
     { "name": "camel.management.openapiUiSpecPath", "required": false, 
"description": "Path or URL of the OpenAPI document loaded by Swagger UI at 
\/q\/openapi.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "defaultValue": "\/q\/openapi.json", 
"secret": false },
     { "name": "camel.management.path", "required": false, "description": 
"Context-path to use for embedded HTTP server", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "defaultValue": "\/", "secret": false 
},
-    { "name": "camel.management.port", "required": false, "description": "Port 
to use for binding embedded HTTP management server. Use 0 to dynamic assign a 
free random port number.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"integer", "javaType": "int", "defaultValue": 8080, "secret": false },
+    { "name": "camel.management.port", "required": false, "description": "Port 
to use for binding embedded HTTP management server. Use 0 to dynamic assign a 
free random port number. When the embedded HTTP server is enabled with the same 
port (both default to 8080), the management endpoints are served by the HTTP 
server, which cannot apply a host, path, SSL or authentication of the 
management server's own. The management server then fails to start when such a 
setting is configured. Use a  [...]
     { "name": "camel.management.sendEnabled", "required": false, 
"description": "Whether to enable sending messages to Camel via HTTP. This 
makes it possible to use Camel to send messages to Camel endpoint URIs via 
HTTP.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"boolean", "javaType": "boolean", "defaultValue": false, "secret": false, 
"security": "insecure:dev" },
     { "name": "camel.management.uploadEnabled", "required": false, 
"description": "Whether to enable file upload via HTTP (not intended for 
production use). This functionality is for development to be able to reload 
Camel routes and code with source changes (if reload is enabled). If enabled 
then you can upload\/delete files via HTTP PUT\/DELETE on context-path: 
\/q\/upload\/{name}. You must also configure the uploadSourceDir option.", 
"sourceType": "org.apache.camel.main.HttpManagementS [...]
     { "name": "camel.management.uploadSourceDir", "required": false, 
"description": "Source directory when upload is enabled.", "sourceType": 
"org.apache.camel.main.HttpManagementServerConfigurationProperties", "type": 
"string", "javaType": "java.lang.String", "secret": false },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 75306c4f9e1f..884a26ccd412 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -272,7 +272,7 @@ The camel.management supports 31 options, which are listed 
below.
 | `camel.management.openapiUiEnabled` | Whether to enable Swagger UI for REST 
DSL OpenAPI documents. If enabled then you can browse the API at context-path: 
/q/openapi. The OpenAPI document is expected at openapiUiSpecPath (by default 
/q/openapi.json from REST DSL apiContextPath ). | false | boolean
 | `camel.management.openapiUiSpecPath` | Path or URL of the OpenAPI document 
loaded by Swagger UI at /q/openapi. | /q/openapi.json | String
 | `camel.management.path` | Context-path to use for embedded HTTP server | / | 
String
-| `camel.management.port` | Port to use for binding embedded HTTP management 
server. Use 0 to dynamic assign a free random port number. | 8080 | int
+| `camel.management.port` | Port to use for binding embedded HTTP management 
server. Use 0 to dynamic assign a free random port number. When the embedded 
HTTP server is enabled with the same port (both default to 8080), the 
management endpoints are served by the HTTP server, which cannot apply a host, 
path, SSL or authentication of the management server's own. The management 
server then fails to start when such a setting is configured. Use a different 
port to apply it. | 8080 | int
 | `camel.management.sendEnabled` | Whether to enable sending messages to Camel 
via HTTP. This makes it possible to use Camel to send messages to Camel 
endpoint URIs via HTTP. | false | boolean
 | `camel.management.uploadEnabled` | Whether to enable file upload via HTTP 
(not intended for production use). This functionality is for development to be 
able to reload Camel routes and code with source changes (if reload is 
enabled). If enabled then you can upload/delete files via HTTP PUT/DELETE on 
context-path: /q/upload/\{name}. You must also configure the uploadSourceDir 
option. | false | boolean
 | `camel.management.uploadSourceDir` | Source directory when upload is 
enabled. |  | String
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/HttpManagementServerConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/HttpManagementServerConfigurationProperties.java
index 17b788f8a690..19ff8fa6af66 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/HttpManagementServerConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/HttpManagementServerConfigurationProperties.java
@@ -130,6 +130,10 @@ public class HttpManagementServerConfigurationProperties 
implements BootstrapClo
 
     /**
      * Port to use for binding embedded HTTP management server. Use 0 to 
dynamic assign a free random port number.
+     *
+     * When the embedded HTTP server is enabled with the same port (both 
default to 8080), the management endpoints are
+     * served by the HTTP server, which cannot apply a host, path, SSL or 
authentication of the management server's own.
+     * The management server then fails to start when such a setting is 
configured. Use a different port to apply it.
      */
     public void setPort(int port) {
         this.port = port;
@@ -456,6 +460,10 @@ public class HttpManagementServerConfigurationProperties 
implements BootstrapClo
 
     /**
      * Port to use for binding embedded HTTP management server. Use 0 to 
dynamic assign a free random port number.
+     *
+     * When the embedded HTTP server is enabled with the same port (both 
default to 8080), the management endpoints are
+     * served by the HTTP server, which cannot apply a host, path, SSL or 
authentication of the management server's own.
+     * The management server then fails to start when such a setting is 
configured. Use a different port to apply it.
      */
     public HttpManagementServerConfigurationProperties withPort(int port) {
         this.port = port;
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index 8aca38ecb262..a6c938e75b24 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -225,6 +225,22 @@ A `BasicMessageFilter` created in application code applies 
a `SpringWebserviceHe
 created with another strategy. A route that relies on the previous behaviour 
can supply a custom
 `headerFilterStrategy` on the `spring-ws` endpoint.
 
+=== camel-platform-http-main - management server settings on a shared port
+
+When the HTTP server (`camel.server.enabled=true`) and the HTTP management 
server (`camel.management.enabled=true`)
+have the same port (both default to 8080), the HTTP server serves the 
management endpoints. It cannot apply these
+options of the management server, which were ignored without notice:
+
+* `camel.management.host`, when set to another host than the one of the HTTP 
server
+* `camel.management.path`, when set to another path than the one of the HTTP 
server
+* `camel.management.useGlobalSslContextParameters=true`, when the HTTP server 
does not use the global SSL configuration
+* `camel.management.authenticationEnabled=true`, with the basic or JWT 
authentication options
+
+Camel now fails to start when the management server shares the port and one of 
them is configured, with a message
+that lists them. Set `camel.management.port` to another port, so that the 
management server runs a server of its own
+and applies them. To keep a single port, remove them and configure the HTTP 
server instead: for example,
+authentication configured on the HTTP server for `/*` also applies to the 
management endpoints.
+
 === camel-mina - the host name of the server is verified over SSL
 
 When `sslContextParameters` is set (on the endpoint, or with 
`useGlobalSslContextParameters` on the component), the
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 8950a78230aa..f756002ec730 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
@@ -38,6 +38,22 @@ as `Failed to connect, because a certificate or security 
check failed`. To resto
 The certificate that the user name and password are encrypted with is checked 
by the same validator. Endpoints that
 use the security policy `None` are not affected.
 
+=== camel-platform-http-main - management server settings on a shared port
+
+When the HTTP server (`camel.server.enabled=true`) and the HTTP management 
server (`camel.management.enabled=true`)
+have the same port (both default to 8080), the HTTP server serves the 
management endpoints. It cannot apply these
+options of the management server, which were ignored without notice:
+
+* `camel.management.host`, when set to another host than the one of the HTTP 
server
+* `camel.management.path`, when set to another path than the one of the HTTP 
server
+* `camel.management.useGlobalSslContextParameters=true`, when the HTTP server 
does not use the global SSL configuration
+* `camel.management.authenticationEnabled=true`, with the basic or JWT 
authentication options
+
+Camel now fails to start when the management server shares the port and one of 
them is configured, with a message
+that lists them. Set `camel.management.port` to another port, so that the 
management server runs a server of its own
+and applies them. To keep a single port, remove them and configure the HTTP 
server instead: for example,
+authentication configured on the HTTP server for `/*` also applies to the 
management endpoints.
+
 === camel-elasticsearch - the credentials are only sent to the nodes of the 
cluster
 
 The `user` and `password` are now offered only to the nodes the client talks 
to: the hosts of `hostAddresses` and,
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 7e9cb0ad2b31..833976bfad7e 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -948,6 +948,22 @@ expanded, and the declaration itself is not passed on to 
Smooks.
 Set `allowExternalEntities=true` on the endpoint or on the data format for 
documents that rely on external entities or
 an external DTD.
 
+=== camel-platform-http-main - management server settings on a shared port
+
+When the HTTP server (`camel.server.enabled=true`) and the HTTP management 
server (`camel.management.enabled=true`)
+have the same port (both default to 8080), the HTTP server serves the 
management endpoints. It cannot apply these
+options of the management server, which were ignored without notice:
+
+* `camel.management.host`, when set to another host than the one of the HTTP 
server
+* `camel.management.path`, when set to another path than the one of the HTTP 
server
+* `camel.management.useGlobalSslContextParameters=true`, when the HTTP server 
does not use the global SSL configuration
+* `camel.management.authenticationEnabled=true`, with the basic or JWT 
authentication options
+
+Camel now fails to start when the management server shares the port and one of 
them is configured, with a message
+that lists them. Set `camel.management.port` to another port, so that the 
management server runs a server of its own
+and applies them. To keep a single port, remove them and configure the HTTP 
server instead: for example,
+authentication configured on the HTTP server for `/*` also applies to the 
management endpoints.
+
 === camel-ical - each unmarshal parses with its own calendar builder
 
 The `ical` data format used one ical4j `CalendarBuilder` for all exchanges. 
Two exchanges that were unmarshalled at
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index e65becbd5562..0f4b3fd33290 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -620,9 +620,7 @@ public class KameletMain extends MainCommandLineSupport {
         if (mcp) {
             configure().httpManagementServer().withEnabled(true);
             configure().httpManagementServer().withMcpEnabled(true);
-            if (!isConfigured("camel.management.host")) {
-                configure().httpManagementServer().withHost("127.0.0.1");
-            }
+            // the management server is bound to 127.0.0.1 in autoconfigure, 
when all the properties can be resolved
             String listeners = 
getInitialProperties().getProperty("camel.main.mainListenerClasses");
             String embedded = 
"org.apache.camel.component.mcp.server.jbang.JbangDevMcpMainListener";
             if (listeners == null || listeners.isBlank()) {
@@ -881,6 +879,9 @@ public class KameletMain extends MainCommandLineSupport {
         ClassLoader cl = createApplicationContextClassLoader(camelContext);
         // create classloader that may include additional JARs
         camelContext.setApplicationContextClassLoader(cl);
+        if ("true".equals(getInitialProperties().get(getInstanceType() + 
".mcp"))) {
+            applyMcpManagementHost(camelContext);
+        }
         // auto configure camel afterwards
         super.autoconfigure(camelContext);
     }
@@ -1089,6 +1090,35 @@ public class KameletMain extends MainCommandLineSupport {
         return false;
     }
 
+    /**
+     * camel run --mcp binds the management server to 127.0.0.1, unless 
camel.management.host is configured, or the
+     * management server shares the port of the HTTP server, which then serves 
it on its own host (another host would
+     * fail the startup). Decided before the auto configuration, when every 
property source, such as
+     * application.properties, can be resolved.
+     */
+    void applyMcpManagementHost(CamelContext camelContext) {
+        var pc = camelContext.getPropertiesComponent();
+        if (pc.resolveProperty("camel.management.host").isPresent()) {
+            return;
+        }
+        boolean serverEnabled = 
pc.resolveProperty("camel.server.enabled").map(v -> 
"true".equalsIgnoreCase(v.trim()))
+                .orElse(configure().httpServer().isEnabled());
+        if (serverEnabled) {
+            try {
+                int port = pc.resolveProperty("camel.server.port").map(v -> 
Integer.parseInt(v.trim()))
+                        .orElse(configure().httpServer().getPort());
+                int managementPort = 
pc.resolveProperty("camel.management.port").map(v -> Integer.parseInt(v.trim()))
+                        .orElse(configure().httpManagementServer().getPort());
+                if (port == managementPort) {
+                    return;
+                }
+            } catch (NumberFormatException e) {
+                // cannot tell, so keep the management server on 127.0.0.1
+            }
+        }
+        configure().httpManagementServer().withHost("127.0.0.1");
+    }
+
     private static String getPid() {
         return String.valueOf(ProcessHandle.current().pid());
     }
diff --git 
a/dsl/camel-kamelet-main/src/test/java/org/apache/camel/main/KameletMainMcpManagementHostTest.java
 
b/dsl/camel-kamelet-main/src/test/java/org/apache/camel/main/KameletMainMcpManagementHostTest.java
new file mode 100644
index 000000000000..aed2acaed2d4
--- /dev/null
+++ 
b/dsl/camel-kamelet-main/src/test/java/org/apache/camel/main/KameletMainMcpManagementHostTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.main;
+
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * The dev MCP binds the management server to 127.0.0.1, which a management 
server that shares the port of the HTTP
+ * server cannot apply.
+ */
+class KameletMainMcpManagementHostTest {
+
+    @Test
+    void bindsTheManagementServerToLoopback() throws Exception {
+        assertEquals("127.0.0.1", managementHost(null));
+    }
+
+    @Test
+    void bindsTheManagementServerWithItsOwnPortToLoopback() throws Exception {
+        assertEquals("127.0.0.1", managementHost(null, "camel.server.enabled", 
"true", "camel.management.port", "9876"));
+    }
+
+    @Test
+    void keepsTheHostWhenSharingThePortOfTheHttpServer() throws Exception {
+        // such as camel run --mcp --port 8080
+        assertEquals("0.0.0.0", managementHost(null, "camel.server.enabled", 
"true"));
+        assertEquals("0.0.0.0",
+                managementHost(null, "camel.server.enabled", "true", 
"camel.server.port", "0", "camel.management.port", "0"));
+    }
+
+    @Test
+    void keepsTheHostWhenTheHttpServerIsEnabledInApplicationProperties() 
throws Exception {
+        assertEquals("0.0.0.0", 
managementHost("classpath:org/apache/camel/main/mcp-shared-port.properties"));
+    }
+
+    @Test
+    void leavesAConfiguredHostToCamelMain() throws Exception {
+        // camel-main binds camel.management.host later on
+        assertEquals("0.0.0.0", managementHost(null, "camel.management.host", 
"192.168.1.10"));
+    }
+
+    private static String managementHost(String location, String... 
properties) throws Exception {
+        KameletMain main = new KameletMain("camel.jbang");
+        try (CamelContext context = new DefaultCamelContext()) {
+            Properties initial = new Properties();
+            for (int i = 0; i < properties.length; i += 2) {
+                initial.setProperty(properties[i], properties[i + 1]);
+            }
+            context.getPropertiesComponent().setInitialProperties(initial);
+            if (location != null) {
+                context.getPropertiesComponent().setLocation(location);
+            }
+            main.applyMcpManagementHost(context);
+        }
+        return main.configure().httpManagementServer().getHost();
+    }
+}
diff --git 
a/dsl/camel-kamelet-main/src/test/resources/org/apache/camel/main/mcp-shared-port.properties
 
b/dsl/camel-kamelet-main/src/test/resources/org/apache/camel/main/mcp-shared-port.properties
new file mode 100644
index 000000000000..ac2e40772f14
--- /dev/null
+++ 
b/dsl/camel-kamelet-main/src/test/resources/org/apache/camel/main/mcp-shared-port.properties
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+# as in an application.properties of camel run --mcp, without --port
+camel.server.enabled=true

Reply via email to