keploy / keploy/keploy

[bug]: Resource leak due to early returns in proxy cleanup functions

Open
#3,342 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug keploy
Dominant language
Go
Stars
18.5k
Forks
2.4k
Avg merge
1d 4h
Merged PRs (30d)
101

Description

👀 Is there an existing issue for this?
  • I have searched and didn't find similar issue
👍 Current behavior

When Keploy attempts to stop the proxy server or clean up proxy connections,
two cleanup functions return early on error, which prevents the rest of the
shutdown logic from running.

In StopProxyServer(), if closing any client connection fails, the function returns
immediately. This skips unlocking the mutex, stopping DNS servers, closing the
listener, and closing the error channel.

Similarly, in handleIncomingConnection(), the deferred cleanup block returns early
when srcConn.Close() or dstConn.Close() returns an error. As a result, the parser
error group is never waited on, and some connections remain unclosed.

This leads to resource leaks, potential deadlocks, and inconsistent proxy shutdown.

What i expect:
Cleanup should always complete, even if one step fails.

The proxy should:

  • Unlock mutexes
  • Close all connections
  • Close listeners
  • Stop DNS servers
  • Close error channels
  • Wait for parser goroutines

Errors should be logged, but cleanup should continue instead of returning early.

why this is critical:

  • Causes resource leaks in production
  • Can deadlock future proxy start/stop cycles
  • Leaks DNS servers, network listeners, goroutines
  • Common cleanup anti-pattern (return inside defer / cleanup loop)
  • Affects stability of Keploy proxy mode
👟 Steps to Replicate
  1. Start Keploy proxy in a test environment.
  2. Simulate a client connection that fails during Close()
    (e.g., closed by another goroutine or forced failure in custom test).
  3. Call StopProxyServer().
  4. Observe:
    • mutex remains locked
    • DNS servers still running
    • listener still bound
    • error channel not closed
    • goroutines left hanging
  5. Run a second proxy start/stop cycle → observe deadlock / leaked resources.
    or use the test provided in the repo to observe it more clearly . here is the exack terminal screenshot after running the test:
Image
📜 Logs (if any)

No specific Keploy logs—error is visible by instrumenting Close() failures
and observing skipped cleanup and hanging goroutines.

💻 Operating system

Linux

🧾 System Info (uname -a)

Linux (WSL2 Ubuntu environment)

📦 OS Release Info (cat /etc/os-release)

NAME="Ubuntu"
VERSION="22.04 LTS"

🐳 Docker Info (if applicable)

Yes, running inside Docker.

  • Docker version: 24.0.2
  • Docker Desktop version: 4.24.2
  • Build image: golang:1.21-alpine
  • Runtime image: alpine:3.18
🧱 Your Environment

Running on local machine (WSL2) .

🎲 Version

Keploy 2.11.31

📦 Repository

keploy

🤔 What use case were you trying? (optional)

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating StopProxyServer() and handleIncomingConnection() in the proxy implementation, then inspect the cleanup paths and the repository test mentioned in the issue. Reproduce a Close() failure and verify that cleanup continues through mutex unlocking, connection and listener closure, DNS shutdown, error-channel closure, and parser-goroutine waiting without leaving the next proxy cycle blocked.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.