Spring Boot
TLS
HTTPS
security configuration
error handling

Bad Request - This combination of host and port requires TLS. with Spring Boot

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

This error usually means one side expects HTTPS while the request actually arrives as plain HTTP. In Spring Boot deployments, the root cause is often simple: the client is talking http:// to a port configured for TLS, or a reverse proxy is terminating TLS without forwarding the protocol information correctly.

The Basic Mismatch

If your app listens with TLS on port 8443, the request must arrive as HTTPS.

Wrong:

text
http://localhost:8443

Right:

text
https://localhost:8443

When the protocols do not match, the embedded server sees bytes that do not make sense for the expected port and returns a bad request or TLS-related error.

A Typical Spring Boot SSL Setup

A minimal TLS configuration in application.yml looks like this:

yaml
1server:
2  port: 8443
3  ssl:
4    enabled: true
5    key-store: classpath:keystore.p12
6    key-store-password: changeit
7    key-store-type: PKCS12
8    key-alias: myapp

With a setup like this, you must use https:// when calling port 8443.

Reverse Proxy Deployments Change the Picture

If Nginx, Apache, or a load balancer terminates TLS in front of Spring Boot, the backend app may receive plain HTTP from the proxy while the browser used HTTPS at the edge. In that case, Boot needs correct forwarded-header handling so it understands the original scheme.

yaml
server:
  forward-headers-strategy: framework

Without that, redirects, generated links, or security filters may behave as if the request were plain HTTP, even though the external client used HTTPS.

Common Real-World Causes

This error often comes from one of these situations:

  • using http:// against an HTTPS port
  • hitting the wrong port entirely
  • proxy SSL termination without proper forwarded headers
  • local testing with mixed self-signed and non-TLS URLs
  • browser bookmarks or health checks pointing to the wrong scheme

The fix depends on which layer is misaligned.

Separate HTTP and HTTPS Clearly

If you intentionally support both HTTP and HTTPS, be explicit about how each port behaves. Some teams expose HTTP only for redirecting to HTTPS, while others allow only HTTPS.

What matters is consistency. A port should not ambiguously expect both at once.

Command-Line Testing Helps

A quick curl check often exposes the mismatch immediately. If HTTPS is configured, test the secure URL explicitly instead of relying on a browser auto-completion habit.

bash
curl -vk https://localhost:8443/actuator/health

If that works while http://localhost:8443 fails, the problem is exactly the protocol mismatch the error message is pointing at.

Debugging Checklist

Start with the simplest checks first:

  1. confirm which port is configured for TLS
  2. confirm the client URL uses the matching scheme
  3. inspect proxy or load balancer SSL termination
  4. verify forwarded-header handling in Boot
  5. review server logs for connector-level errors

Most of the time, the problem is visible within those five steps.

Common Pitfalls

  • Testing an HTTPS port with http:// is the classic cause.
  • Assuming the proxy and Spring Boot agree on scheme handling without configuration often causes redirect loops and bad-request errors.
  • Mixing ports during local development makes certificate or TLS issues look more mysterious than they are.
  • Fixing only the client URL when the real problem is missing forwarded headers solves the symptom but not the deployment setup.
  • Treating this as a Spring business-logic problem instead of a transport-layer mismatch slows debugging down.

Summary

  • This error usually means plain HTTP was sent where TLS was required.
  • In Spring Boot, check the port, the scheme, and whether SSL is enabled for that connector.
  • If a reverse proxy terminates TLS, configure forwarded-header handling correctly.
  • Keep HTTP and HTTPS roles explicit in your deployment.
  • Debug from the transport layer upward, because the problem is usually below the application logic.

Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design