or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

conditional-annotations.mdcore-infrastructure.mdendpoint-filtering.mdendpoint-properties.mdindex.mdjmx-endpoints.mdmanagement-endpoints.mdmanagement-server.mdweb-endpoints.md
tile.json

management-server.mddocs/

Management Server Configuration

Configuration for running management endpoints on a separate server port with independent SSL and settings.

Imports

import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;

Quick Reference

Port Configuration

# Same port (default)
# No configuration needed

# Separate port
management.server.port=8081

# Disable management
management.server.port=-1

ManagementPortType Determination

Property ValueResultUse Case
Not setSAMEDefault, simplest
Same as server.portSAMEExplicit same port
Different numberDIFFERENTNetwork isolation
-1DISABLEDDisable management

API Reference

ManagementContextAutoConfiguration

/**
 * Auto-configuration for the management context
 * Creates either a same-context or separate child context configuration
 * based on management.server.port setting
 *
 * @since 2.0.0
 */
@AutoConfiguration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
public final class ManagementContextAutoConfiguration {

    /**
     * Configuration for when management endpoints run on same port as application
     * Validates that management-specific SSL and address are not configured
     * Adds 'local.management.port' property alias
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnManagementPort(ManagementPortType.SAME)
    static class SameManagementContextConfiguration implements SmartInitializingSingleton {

        /**
         * Constructor injecting environment for validation
         * @param environment Spring environment
         */
        SameManagementContextConfiguration(Environment environment);

        /**
         * Called after all singletons are instantiated
         * Performs validation and property alias setup
         */
        @Override
        void afterSingletonsInstantiated();

        /**
         * Inner configuration that enables ManagementContextConfiguration imports
         * for SAME context type
         */
        @Configuration(proxyBeanMethods = false)
        @EnableManagementContext(ManagementContextType.SAME)
        static class EnableSameManagementContextConfiguration {
        }
    }

    /**
     * Configuration for when management endpoints run on different port
     * Enables ManagementServerProperties and creates child context initializer
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
    @EnableConfigurationProperties(ManagementServerProperties.class)
    static class DifferentManagementContextConfiguration {

        /**
         * Creates child management context initializer for separate management port
         * ManagementContextFactory is injected as parameter (not created by this config)
         * @param managementContextFactory Factory for creating management context
         * @param parentContext The parent application context
         * @return Child context initializer
         */
        @Bean
        static ChildManagementContextInitializer childManagementContextInitializer(
            ManagementContextFactory managementContextFactory,
            AbstractApplicationContext parentContext
        );
    }
}

Key Behavior:

  • SameManagementContextConfiguration: Active when management.server.port is not set or same as server.port

    • Validates that management-specific SSL is not configured (throws exception if management.server.ssl.enabled=true)
    • Validates that management-specific address is not configured (throws exception if management.server.address is set)
    • Adds property alias so local.management.port resolves to local.server.port
    • Enables ManagementContextType.SAME configurations via @EnableManagementContext
  • DifferentManagementContextConfiguration: Active when management.server.port is set to a different port

    • Creates ChildManagementContextInitializer bean for setting up separate management context
    • Enables ManagementServerProperties configuration properties
    • Management context runs as a child context with separate web server

ManagementServerProperties

@ConfigurationProperties("management.server")
public class ManagementServerProperties {

    private Integer port;             // null = same as server.port, -1 = disabled, other = separate port
    private InetAddress address;      // Bind address (default: same as server.address)
    private String basePath = "";     // Additional base path (applied after endpoints.web.base-path)
    private Ssl ssl;                  // SSL configuration (only for separate port)

    public @Nullable Ssl getSsl();
    public void setSsl(@Nullable Ssl ssl);
}

ManagementPortType

/**
 * Type of management port configuration
 */
public enum ManagementPortType {
    DISABLED,   // management.server.port=-1
    SAME,       // port not set or same as server.port
    DIFFERENT;  // separate port specified

    /**
     * Determines type from environment
     * Logic:
     * - DISABLED: if management.server.port < 0
     * - SAME: if management.server.port is null OR
     *         (server.port is null AND management.server.port == 8080) OR
     *         (management.server.port != 0 AND management.server.port == server.port)
     * - DIFFERENT: otherwise
     */
    public static ManagementPortType get(Environment environment);
}

AccessLogCustomizer

/**
 * Base class for customizing web server access logs
 * Extends WebServerFactoryCustomizer to allow prefix customization
 *
 * @param <T> the WebServerFactory type that can be customized
 * @since 4.0.0
 */
public abstract class AccessLogCustomizer<T extends WebServerFactory>
        implements WebServerFactoryCustomizer<T>, Ordered {

    /**
     * Creates an access log customizer with optional prefix
     * @param prefix Optional prefix to apply to access log file names
     */
    protected AccessLogCustomizer(@Nullable String prefix);

    /**
     * Customizes the access log prefix
     * If prefix is null, returns existingPrefix unchanged
     * If existingPrefix is null, returns this prefix
     * If existingPrefix already starts with this prefix, returns existingPrefix unchanged
     * Otherwise, prepends this prefix to existingPrefix
     *
     * @param existingPrefix The existing prefix (may be null)
     * @return The customized prefix (may be null)
     */
    protected @Nullable String customizePrefix(@Nullable String existingPrefix);

    /**
     * Returns the order for this customizer (default: 1)
     * @return The order value
     */
    @Override
    public int getOrder();
}

Usage Example:

@Bean
public AccessLogCustomizer<TomcatServletWebServerFactory> managementAccessLogCustomizer() {
    return new AccessLogCustomizer<>("management-") {
        @Override
        public void customize(TomcatServletWebServerFactory factory) {
            AccessLogValve valve = new AccessLogValve();
            valve.setPrefix(customizePrefix(valve.getPrefix()));
            factory.addEngineValves(valve);
        }
    };
}

ConditionalOnManagementPort

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(OnManagementPortCondition.class)
public @interface ConditionalOnManagementPort {
    ManagementPortType value();
}

ManagementWebServerFactoryCustomizer

/**
 * WebServerFactoryCustomizer that customizes the WebServerFactory used to
 * create the management context's web server.
 *
 * Applies management-specific configuration including port, SSL, address,
 * and server header settings. Also inherits parent context customizations
 * (e.g., access logs) while resetting error pages.
 *
 * @param <T> the type of web server factory to customize
 * @since 2.0.0
 */
public class ManagementWebServerFactoryCustomizer<T extends ConfigurableWebServerFactory>
        implements WebServerFactoryCustomizer<T>, Ordered {

    /**
     * Creates a new customizer that will retrieve beans using the given beanFactory
     * @param beanFactory the bean factory to use
     * @since 3.5.0
     */
    public ManagementWebServerFactoryCustomizer(ListableBeanFactory beanFactory);

    /**
     * Customizes the web server factory with management-specific settings
     * - Sets management port from ManagementServerProperties
     * - Configures SSL if specified in management properties
     * - Sets server header from ServerProperties
     * - Sets bind address from ManagementServerProperties
     * - Resets error pages to empty set
     * - Inherits parent context customizations (e.g., access logs)
     *
     * @param factory the web server factory to customize
     */
    @Override
    public void customize(T factory);

    /**
     * Returns the order for this customizer (default: 0)
     * @return The order value
     */
    @Override
    public int getOrder();

    /**
     * Protected method for subclasses to apply additional customizations
     * @param factory the web server factory
     * @param managementServerProperties management server properties
     * @param serverProperties server properties
     */
    protected void customize(T factory, ManagementServerProperties managementServerProperties,
            ServerProperties serverProperties);
}

Key Behavior:

  • Automatically registered when using separate management port
  • Inherits parent context's web server customizations (e.g., access log configuration)
  • Resets error pages to prevent leaking application error details on management port
  • Applies management-specific SSL configuration independent of application SSL

Usage: This class is used internally by the management context infrastructure. Users typically don't need to interact with it directly, but can extend it for custom management server factory customization.

@EnableManagementContext

/**
 * Annotation that enables management context configuration import
 * Used to import ManagementContextConfigurationImportSelector
 * Package-private internal annotation - not part of public API
 *
 * @since 2.0.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ManagementContextConfigurationImportSelector.class)
@interface EnableManagementContext {
    /**
     * The type of management context to enable
     * @return Management context type
     */
    ManagementContextType value();
}

ManagementContextFactory

/**
 * Factory for creating management context instances
 * Creates web server application contexts for management endpoints when using separate management port
 *
 * This is the concrete implementation used by Spring Boot's management context infrastructure.
 * For internal use, but can be customized if needed for advanced scenarios.
 *
 * @since 4.0.0
 */
public final class ManagementContextFactory {

    /**
     * Creates a management context factory
     * @param webApplicationType The web application type (SERVLET or REACTIVE)
     * @param webServerFactoryClass The web server factory class to use (e.g., TomcatServletWebServerFactory)
     * @param autoConfigurationClasses Auto-configuration classes to apply to the management context
     */
    public ManagementContextFactory(
        WebApplicationType webApplicationType,
        Class<? extends WebServerFactory> webServerFactoryClass,
        Class<?>... autoConfigurationClasses
    );

    /**
     * Creates a management context with the given parent context
     * @param parentContext The parent application context
     * @return The created management application context
     */
    public ConfigurableApplicationContext createManagementContext(ApplicationContext parentContext);

    /**
     * Registers web server factory beans in the management context
     * Called during context initialization to set up the web server
     * @param parentContext The parent application context
     * @param managementContext The management context being configured
     * @param registry The annotation config registry for bean registration
     */
    public void registerWebServerFactoryBeans(
        ApplicationContext parentContext,
        ConfigurableApplicationContext managementContext,
        AnnotationConfigRegistry registry
    );
}

Note: This class is primarily for internal use by the management context infrastructure. It is automatically configured when using management.server.port with a different port. Custom management context creation is rarely needed.

ChildManagementContextInitializer

/**
 * ApplicationContextInitializer that configures the child management context
 * Applies when using separate management port (DIFFERENT)
 *
 * @since 2.0.0
 */
public class ChildManagementContextInitializer
        implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    /**
     * Initializes the child management context
     * Sets up parent context reference, environment, and bean factory post-processors
     *
     * @param applicationContext The child management context to initialize
     */
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext);
}

ManagementContextConfigurationImportSelector

/**
 * ImportSelector that imports management context configurations
 *
 * Implementation Details:
 * - Implements DeferredImportSelector (not just ImportSelector) for late evaluation
 * - Reads from META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports
 * - Filters configurations based on @ManagementContextConfiguration annotation's value()
 * - Only imports configurations matching current ManagementContextType:
 *   - ManagementContextType.SAME: Imports SAME and ANY configurations
 *   - ManagementContextType.CHILD: Imports CHILD and ANY configurations
 *   - ManagementContextType.ANY: Always imported regardless of context type
 * - Uses Spring's ImportCandidates mechanism for reading imports files
 * - Processes @ManagementContextConfiguration annotation on each candidate class
 *
 * Import File Format:
 * - Location: META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports
 * - Format: One fully-qualified class name per line
 * - Comments: Lines starting with # are ignored
 * - Each class must be annotated with @ManagementContextConfiguration
 *
 * @since 2.0.0
 */
public class ManagementContextConfigurationImportSelector implements DeferredImportSelector {

    /**
     * Selects management context configuration classes to import
     *
     * Selection Process:
     * 1. Read @EnableManagementContext annotation from importing class
     * 2. Get ManagementContextType from annotation's value() attribute
     * 3. Load candidates from ManagementContextConfiguration.imports file
     * 4. For each candidate class:
     *    a. Check if it has @ManagementContextConfiguration annotation
     *    b. Get the annotation's value() (context type)
     *    c. Include if value is ANY or matches current context type
     * 5. Return filtered list of configuration class names
     *
     * @param importingClassMetadata Metadata of the importing class (must have @EnableManagementContext)
     * @return Array of filtered configuration class names to import
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata);
}

OnManagementPortCondition

/**
 * Condition that matches based on management port type
 * Used by @ConditionalOnManagementPort annotation
 *
 * @since 2.0.0
 */
public class OnManagementPortCondition extends SpringBootCondition {

    /**
     * Determines the condition outcome based on management port configuration
     * Evaluates ManagementPortType.get(environment) against expected value
     *
     * @param context The condition context
     * @param metadata The annotation metadata
     * @return Condition outcome (match or no match)
     */
    @Override
    public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata);
}

Configuration Examples

Same Port (Default)

# No configuration needed
server.port=8080

# URLs:
# - Application: http://localhost:8080
# - Actuator: http://localhost:8080/actuator/*

Separate Port

server.port=8080
management.server.port=8081

# URLs:
# - Application: http://localhost:8080
# - Actuator: http://localhost:8081/actuator/*

Separate Port with Base Path

server.port=8080
management.server.port=8081
management.server.base-path=/admin
management.endpoints.web.base-path=/actuator

# URLs:
# - Application: http://localhost:8080
# - Actuator: http://localhost:8081/admin/actuator/*

Separate Port with SSL

# Application (HTTP)
server.port=8080

# Management (HTTPS)
management.server.port=8443
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:management-keystore.p12
management.server.ssl.key-store-password=changeit
management.server.ssl.key-store-type=PKCS12

# URLs:
# - Application: http://localhost:8080
# - Actuator: https://localhost:8443/actuator/*

Both with SSL (Different Certificates)

# Application
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:server-keystore.p12
server.ssl.key-store-password=server-secret

# Management
management.server.port=9443
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:management-keystore.p12
management.server.ssl.key-store-password=management-secret

Localhost-Only Management

# Application: all interfaces
server.port=8080
server.address=0.0.0.0

# Management: localhost only
management.server.port=8081
management.server.address=127.0.0.1

Disable Management

management.server.port=-1

# All management endpoints disabled

Decision Matrix

When to Use Separate Port

RequirementSame PortSeparate PortReason
Simple setupLess configuration
Network isolationCan restrict firewall access
Different SSLSeparate certificates
Localhost-only managementBind to 127.0.0.1
Docker/K8s health checksLiveness on main port
Internal monitoringSeparate security policies

Architecture

Same Port Architecture

┌─────────────────────────────────┐
│   Application Context           │
│  ┌──────────────────────────┐   │
│  │  Web Server (8080)       │   │
│  │  ├─ App Endpoints        │   │
│  │  └─ Actuator Endpoints   │   │
│  └──────────────────────────┘   │
└─────────────────────────────────┘

Separate Port Architecture

┌──────────────────────────────────────┐
│   Parent Application Context         │
│  ┌──────────────────────────────┐    │
│  │  Main Web Server (8080)      │    │
│  │  └─ App Endpoints            │    │
│  └──────────────────────────────┘    │
│                                      │
│  ┌──────────────────────────────┐    │
│  │  Child Management Context     │    │
│  │  ┌─────────────────────────┐ │    │
│  │  │ Mgmt Server (8081)      │ │    │
│  │  │ └─ Actuator Endpoints   │ │    │
│  │  └─────────────────────────┘ │    │
│  └──────────────────────────────┘    │
└──────────────────────────────────────┘

Conditional Beans

Same Port Configuration

@Bean
@ConditionalOnManagementPort(ManagementPortType.SAME)
public SamePortSecurityFilter samePortSecurityFilter() {
    return new SamePortSecurityFilter();
}

Separate Port Configuration

@Bean
@ConditionalOnManagementPort(ManagementPortType.DIFFERENT)
public ManagementPortSecurityFilter managementPortSecurityFilter() {
    return new ManagementPortSecurityFilter();
}

Disabled Configuration

@Bean
@ConditionalOnManagementPort(ManagementPortType.DISABLED)
public NoOpManagementConfiguration noOpConfig() {
    return new NoOpManagementConfiguration();
}

Management Context

ManagementContextType

public enum ManagementContextType {
    SAME,   // Endpoints in same context as application
    CHILD,  // Endpoints in separate child context
    ANY     // Applies to both
}

ManagementContextConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
public @interface ManagementContextConfiguration {
    ManagementContextType value() default ManagementContextType.ANY;
    boolean proxyBeanMethods() default true;
}

Registration

File: META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports

com.example.CommonManagementConfiguration
com.example.ChildManagementConfiguration

Example

// Applies to both SAME and CHILD
@ManagementContextConfiguration
public class CommonManagementConfiguration {
    @Bean
    public CommonBean commonBean() {
        return new CommonBean();
    }
}

// Only for CHILD (separate port)
@ManagementContextConfiguration(ManagementContextType.CHILD)
public class ChildManagementConfiguration {
    @Bean
    public ChildOnlyBean childOnlyBean() {
        return new ChildOnlyBean();
    }
}

Spring Security Integration

Same Port Security

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(auth -> auth
        .requestMatchers("/actuator/**").hasRole("ACTUATOR")
        .anyRequest().authenticated());
    return http.build();
}

Separate Port Security

@Configuration
public class SecurityConfiguration {

    // Main application security (port 8080)
    @Bean
    @Order(1)
    public SecurityFilterChain appSecurityFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher(request -> request.getServerPort() == 8080)
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
        return http.build();
    }

    // Management security (port 8081)
    @Bean
    @Order(2)
    public SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
        http.securityMatcher(request -> request.getServerPort() == 8081)
            .authorizeHttpRequests(auth -> auth.anyRequest().hasRole("ACTUATOR"));
        return http.build();
    }
}

Common Issues

Issue: Port Already in Use

Symptom: Address already in use on management port

Solution:

# Change port or use dynamic port
management.server.port=8082
# Or use 0 for random port
management.server.port=0

Issue: Management Endpoints Not Accessible

Cause: Wrong port or base path

Check URL Structure:

<protocol>://<address>:<management.server.port><management.server.base-path><management.endpoints.web.base-path>/<endpoint>

Example:
http://localhost:8081/admin/actuator/health

Issue: SSL Certificate Issues

Cause: Wrong keystore or password

Debug:

logging.level.org.springframework.boot.web.embedded.tomcat.TomcatWebServer=DEBUG

Issue: Child Context Beans Not Found

Cause: Bean defined in wrong context

Solution: Use @ManagementContextConfiguration for management-only beans

Performance Considerations

Separate Port Benefits

  1. Independent Thread Pool: Management doesn't compete with application
  2. Separate Connection Pool: Management has its own connector
  3. Isolation: Management traffic doesn't affect application performance

Overhead

  • Memory: Additional web server instance (~10-20MB)
  • Startup Time: Additional context initialization (~100-500ms)
  • Complexity: More configuration to manage

Use Cases

Development

# Simple same-port setup
server.port=8080
management.endpoints.web.exposure.include=*

Production

# Separate port with network isolation
server.port=8080
server.address=0.0.0.0
management.server.port=8081
management.server.address=10.0.0.10  # Internal network only
management.endpoints.web.exposure.include=health,info,metrics

Kubernetes

# Health checks on main port
management.endpoint.health.probes.enabled=true
server.port=8080

# Full actuator on separate port (not exposed externally)
management.server.port=8081
management.endpoints.web.exposure.include=*

High Security

# Main app: public HTTPS
server.port=443
server.ssl.enabled=true

# Management: internal network, different SSL
management.server.port=8443
management.server.address=10.0.0.10
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:internal-keystore.p12

Related Documentation

  • Web Endpoints - HTTP endpoint exposure
  • Conditional Annotations - Port-based conditions
  • Endpoint Filtering - Endpoint filtering