Bug Fix: Thread Leak in client.go#131
Merged
directionless merged 1 commit intoosquery:masterfrom Feb 26, 2026
Merged
Conversation
directionless
approved these changes
Feb 26, 2026
Member
directionless
left a comment
There was a problem hiding this comment.
Nice finding this. It looks like I introduced this in #108 when I changed the return from return &ExtensionManagerClient{client, trans}, nil to return c, nil
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
We (Elastic) had a customer report excessive resource usage from osqueryd.exe after a recent update of Elastic's osquerybeat.
We did some research, and consulting with Claude a bit, and were able to identify a thread leak in osquery-go. When a program creates a new
NewExtensionManagerClientusing the go bindings,transis created and passed to the factory, but is never assigned to assigned toc.transport. Later, when the client is closed, the client does not close transport, so it is left dangling.When the calling program exits, the threads are cleaned up in osqueryd. However, if the calling program never exits, the threads stay alive in osqueryd in a waiting state indefinitely.
In our case, Osquerybeat was creating a client once every 30s an issuing a query, then closing the client, but staying alive. So the customer saw unrestrained growth of threads in osqueryd.
Solution
The fix is simple, just add the line to assign the transport variable, and it will be closed properly when the client is closed.
Offending Code
osquery-go/client.go
Lines 51 to 88 in f77b3a1
Proof of Concept
I had Claude help me make a proof of concept that exercises this bug
Expand: POC code to trigger the bug