Host and IP Resolution in a Micronaut application with Load Balancer and Elastic Beanstalk

When you run your application behind a Elastic Load Balancer, a Classic Load Balancer or an Application Load Balancer, AWS decorates your request with X-Forward HTTP Headers.

In a Micronaut application, you may need to resolve the domain name of your application, for example when using OAuth 2.0 for a redirect_uri, or restrict an endpoint to a range of IP Addresses, for example a Stripe's callback.

Micronaut® framework contains two APIs:

  • HttpHostResolver to resolve the host
  • HttpClientAddressResolver to resolve the IP.

Given the following controller:


package example.micronaut;

import io.micronaut.http.HttpRequest;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.server.util.HttpClientAddressResolver;
import io.micronaut.http.server.util.HttpHostResolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;

public class HeadersController {

	private static final Logger LOG = LoggerFactory.getLogger(HeadersController.class);

	private final HttpHostResolver httpHostResolver;
	private final HttpClientAddressResolver httpClientAddressResolver;

	public HeadersController(HttpHostResolver httpHostResolver,
							 HttpClientAddressResolver httpClientAddressResolver) {
		this.httpHostResolver = httpHostResolver;
		this.httpClientAddressResolver = httpClientAddressResolver;

	public Map<String, Object> index(HttpRequest<?> request) {
		for (String name : request.getHeaders().names()) {
			if (LOG.isInfoEnabled()) {"H {}: {}", name, request.getHeaders().get(name));
		Map<String, Object> result = new HashMap<>();
		result.put("ip", httpClientAddressResolver.resolve(request));
		result.put("resolved_host", httpHostResolver.resolve(request));
		return result;

If I run this application locally, I get:

% curl localhost:8080

with logs:

H Host: localhost:8080
H User-Agent: curl/7.64.1
H Accept: */*

To resolve the Host and IP in Elastic Beanstalk behind an Application Load Balancer add:


	  protocol-header: X-Forwarded-Proto
	  port-header: X-Forwarded-Port
	  host-header: Host
	client-address-header: X-Real-IP

EC2 environment is automatically detected, because of that I typically use application-ec2.yml for such configuration.

If you call your application's endpoint running in Elastic Beanstalk you get:

% curl http://micronaut.example

with logs:

H Connection: upgrade
H Host: micronaut.example
H X-Real-IP:
H X-Forwarded-For:,
H X-Forwarded-Proto: http
H X-Forwarded-Port: 80
H X-Amzn-Trace-Id: Root=1-60865015-39f63e107ca0f25410b0e66e
H User-Agent: curl/7.64.1
H Accept: */*

Tags: #micronaut #aws #elasticbeanstalk #elasticloadbalancing