Spring Boot "Web server failed to start. Port already in use" - Fix in CI
Spring Boot could not bind its embedded web server because another process already holds the port. In CI this is usually a previous test JVM that did not shut down, or two tests starting full servers on the same fixed port.
What this error means
Startup fails with Web server failed to start. Port 8080 was already in use. and an action suggesting you identify and stop the process or change the port. Tests that boot a real server fail intermittently.
***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure
this application to listen on another port.Common causes
A fixed port across parallel tests
Multiple @SpringBootTest(webEnvironment = DEFINED_PORT) tests, or parallel jobs, all bind the same hardcoded port and the second collides.
A leftover server from a prior step
A previous test or a background app start in the same CI job kept the port held when the next start ran.
A genuinely flaky port handoff
Even with a random port, a slow OS-level release of a just-closed socket can briefly cause a bind clash on a busy runner.
How to fix it
Use a random port for server tests
Let Spring pick a free port per test and inject it, eliminating fixed-port collisions.
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class ApiTest {
@LocalServerPort int port; // unique per context
}Stop running full-server tests in parallel on one port
If a fixed port is required, serialize those tests or give each a distinct port.
# application-test.yml - distinct fixed port for the integration profile
server:
port: 0 # 0 = ephemeral, OS assigns a free portFree a stuck port between steps
As a guard, ensure prior server processes are stopped before the next start.
# CI step: ensure nothing holds 8080 before the next boot
fuser -k 8080/tcp || trueHow to prevent it
- Prefer
RANDOM_PORT/server.port=0for every test that boots a real server. - Never share one fixed port across tests that run in parallel.
- Ensure each test context is closed so its port is released promptly.