title: Spring cloud: Ribbon and HTTPS
body: <p>We want to use HTTPS for our microservices communication based on Feign and Ribbon. The services are based on spring boot and tomcat is correctly setup. The instances are registered with the HTTPS URL and securePort enabled on Eureka. However, when we call another microservice via Feign then the underlying Ribbon doesn't recognizes the protocol and falls back to HTTP. I could solve that problem by adding the protocol to the FeignClient annotation like this:</p>
  
  <pre><code>    @FeignClient("https://users")
  </code></pre>
  
  <p>But it seem that the Zuul proxy and the Hystrix/Turbine which are also using Ribbon internally have the same HTTP fallback problem. Is there any way to configure Ribbon centrally to use HTTPS as default or use the <strong>securePort</strong> setting of the registred eureka instance?</p>
  
  <p>Eureka instance configuration:</p>
  
  <pre><code>eureka.instance.hostname=localhost
  eureka.instance.securePort = ${server.port}
  eureka.instance.securePortEnabled = true  
  eureka.instance.nonSecurePortEnabled = false 
  eureka.instance.metadataMap.hostname = ${eureka.instance.hostname}
  eureka.instance.metadataMap.securePort = ${server.port}
  eureka.instance.homePageUrl = https://${eureka.instance.hostname}:${server.port}/
  eureka.instance.statusPageUrl = https://${eureka.instance.hostname}:${server.port}/admin/info
  </code></pre>
  
  <p>With these settings it looks in Eureka like the service runs on HTTPS. The Zuul proxy runs fine, but uses the HTTP URL to call the service. You have to enable SSL in Spring Boots embedded Tomcat by providing a server certificate in a keystore:</p>
  
  <pre><code>server.ssl.key-store=server.jks
  server.ssl.key-store-password=&lt;pw&gt;
  server.ssl.keyStoreType=jks
  server.ssl.keyAlias=tomcat
  server.ssl.key-password=&lt;pw&gt; 
  </code></pre>
  
  <p>Tomcat than only runs on HTTPS and the HTTP port is blocked, but than I get: <code>localhost:8081 failed to respond</code> because a HTTP URL is used to call the service. By setting <code>ribbon.IsSecure=true</code> the users service url is correctly generated, but the Ribbon loadbalancer fails to lookup the users service in Eureka: <code>Load balancer does not have available server for client: users</code>. I aslo tried to set <code>users.ribbon.IsSecure=true</code> in the zuul proxy only, but still get the same error.</p>
  
  <pre><code>Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: user
  at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:468)
  at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184)
  at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)
  at rx.Observable$1.call(Observable.java:145)
  at rx.Observable$1.call(Observable.java:137)
  at rx.Observable$1.call(Observable.java:145)
  at rx.Observable$1.call(Observable.java:137)
  at rx.Observable.unsafeSubscribe(Observable.java:7304)
  at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:112)
  at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:81)
  at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:59)
  at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:77)
  at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45)
  at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:41)
  at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:30)
  at rx.Observable$1.call(Observable.java:145)
  at rx.Observable$1.call(Observable.java:137)
  at rx.Observable$1.call(Observable.java:145)
  at rx.Observable$1.call(Observable.java:137)
  at rx.Observable$1.call(Observable.java:145)
  at rx.Observable$1.call(Observable.java:137)
  at rx.Observable.subscribe(Observable.java:7393)
  at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:441)
  at rx.observables.BlockingObservable.single(BlockingObservable.java:340)
  at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:102)
  at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:81)
  at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.forward(RibbonCommand.java:129)
  at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:103)
  at org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand.run(RibbonCommand.java:1)
  at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:298)
  </code></pre>