[GH-ISSUE #6225] [Validated]: Panic getting system info in distroless container #11590

Closed
opened 2026-08-05 01:30:06 -04:00 by saavagebueno · 2 comments
Owner

Originally created by @phillebaba on GitHub (May 20, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/6225

Validation checklist

  • This issue is linked to a validated discussion, or it is being opened directly by a maintainer.
  • The report has enough context for engineering to act on it without re-triaging from scratch.
  • Sensitive data, secrets, private keys, internal hostnames, and public IPs have been removed or intentionally disclosed.

Issue type

Bug / Regression

Source discussion

Maintainer-created

Validation owner

@phillebaba

Target repository

netbirdio/netbird

Summary

When starting the embedded client in a distroless image container, a panic will occur when trying to get the system info. This is because the uname binary does not exist. When an error occurs the error is just ignored and the parsing of the output is continued. This in the end results in a panic due to index out of bounds.

Validation evidence

The issue starts here as we ignore the error from the command.
454ff66518/client/system/info_linux.go (L89-L91)

Then we try to parse the failed output and assume that the format is still correct.
454ff66518/client/system/info_linux.go (L38-L40)

Which panics here due to index out of bounds.
454ff66518/client/system/info_linux.go (L62)

The following panic happens.

time="2026-05-20T16:20:52Z" level=warning msg="getInfo: exec: \"uname\": executable file not found in $PATH"
panic: runtime error: index out of range [2] with length 1

goroutine 1 [running]:
github.com/netbirdio/netbird/client/system.GetInfo({0x182dd70, 0x17abfef306f0})
        github.com/netbirdio/netbird@v0.71.2/client/system/info_linux.go:62 +0x65f
github.com/netbirdio/netbird/client/internal/auth.(*Auth).doMgmLogin(0x17abff2aa000, 0x17abff29a080, {0x182dd70?, 0x17abfef306f0?}, {0x17abff29c050, 0x50, 0x50})
        github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:284 +0x46
github.com/netbirdio/netbird/client/internal/auth.(*Auth).Login.func1(0x17abff29a080)
        github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:182 +0xa5
github.com/netbirdio/netbird/client/internal/auth.(*Auth).withRetry.func1()
        github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:413 +0xc5
github.com/cenkalti/backoff/v4.RetryNotifyWithTimer.Operation.withEmptyData.func1()
        github.com/cenkalti/backoff/v4@v4.3.0/retry.go:18 +0x13
github.com/cenkalti/backoff/v4.doRetryNotify[...](0x17abff037900?, {0x7f3735ffa130, 0x17abff29e060}, 0x1808708, {0x0, 0x0?})
        github.com/cenkalti/backoff/v4@v4.3.0/retry.go:88 +0x11c
github.com/cenkalti/backoff/v4.RetryNotifyWithTimer(0x263e810?, {0x7f3735ffa130?, 0x17abff29e060?}, 0x17abff29c050?, {0x0?, 0x0?})
        github.com/cenkalti/backoff/v4@v4.3.0/retry.go:61 +0x56
github.com/cenkalti/backoff/v4.RetryNotify(...)
        github.com/cenkalti/backoff/v4@v4.3.0/retry.go:49
github.com/netbirdio/netbird/client/internal/auth.(*Auth).withRetry(0x17abff2aa000, {0x182dd70, 0x17abfef306f0}, 0x17abff0379e0)
        github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:401 +0x1f0
github.com/netbirdio/netbird/client/internal/auth.(*Auth).Login(0x17abff2aa000, {0x182dd70, 0x17abfef306f0}, {0x7fff13d58d9a, 0x24}, {0x0, 0x0})
        github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:181 +0x130
github.com/netbirdio/netbird/client/embed.(*Client).Start(0x17abfef560c0, {0x182df70, 0x17abff1fa300})
        github.com/netbirdio/netbird@v0.71.2/client/embed/embed.go:229 +0x30f
main.run({0x182dd38, 0x30e03a0}, {0x176110b, 0x4}, {0x0, 0x0}, {0x0, 0x0}, {0x7fff13d58d9a, 0x24}, ...)
        github.com/netbirdio/netbird-kubeapi-proxy/main.go:58 +0x24c
main.main()
        github.com/netbirdio/netbird-kubeapi-proxy/main.go:38 +0x325

Proposed scope

My suggestion is that we refactor the system info logic to use golang.org/x/sys/unix instead of shelling out to uname. This does the same thing but makes the underlying system calls instead of calling the binary. A safer result that does not require hard API requirements on output formats to stdout.

Acceptance criteria

Getting system info in Linux should not be dependent on external binaries.

Additional context

No response

Originally created by @phillebaba on GitHub (May 20, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/6225 ### Validation checklist - [x] This issue is linked to a validated discussion, or it is being opened directly by a maintainer. - [x] The report has enough context for engineering to act on it without re-triaging from scratch. - [x] Sensitive data, secrets, private keys, internal hostnames, and public IPs have been removed or intentionally disclosed. ### Issue type Bug / Regression ### Source discussion Maintainer-created ### Validation owner @phillebaba ### Target repository netbirdio/netbird ### Summary When starting the embedded client in a distroless image container, a panic will occur when trying to get the system info. This is because the `uname` binary does not exist. When an error occurs the error is just ignored and the parsing of the output is continued. This in the end results in a panic due to index out of bounds. ### Validation evidence The issue starts here as we ignore the error from the command. https://github.com/netbirdio/netbird/blob/454ff66518feaef2d9ceb10fb1960da28f14fd87/client/system/info_linux.go#L89-L91 Then we try to parse the failed output and assume that the format is still correct. https://github.com/netbirdio/netbird/blob/454ff66518feaef2d9ceb10fb1960da28f14fd87/client/system/info_linux.go#L38-L40 Which panics here due to index out of bounds. https://github.com/netbirdio/netbird/blob/454ff66518feaef2d9ceb10fb1960da28f14fd87/client/system/info_linux.go#L62 The following panic happens. ``` time="2026-05-20T16:20:52Z" level=warning msg="getInfo: exec: \"uname\": executable file not found in $PATH" panic: runtime error: index out of range [2] with length 1 goroutine 1 [running]: github.com/netbirdio/netbird/client/system.GetInfo({0x182dd70, 0x17abfef306f0}) github.com/netbirdio/netbird@v0.71.2/client/system/info_linux.go:62 +0x65f github.com/netbirdio/netbird/client/internal/auth.(*Auth).doMgmLogin(0x17abff2aa000, 0x17abff29a080, {0x182dd70?, 0x17abfef306f0?}, {0x17abff29c050, 0x50, 0x50}) github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:284 +0x46 github.com/netbirdio/netbird/client/internal/auth.(*Auth).Login.func1(0x17abff29a080) github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:182 +0xa5 github.com/netbirdio/netbird/client/internal/auth.(*Auth).withRetry.func1() github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:413 +0xc5 github.com/cenkalti/backoff/v4.RetryNotifyWithTimer.Operation.withEmptyData.func1() github.com/cenkalti/backoff/v4@v4.3.0/retry.go:18 +0x13 github.com/cenkalti/backoff/v4.doRetryNotify[...](0x17abff037900?, {0x7f3735ffa130, 0x17abff29e060}, 0x1808708, {0x0, 0x0?}) github.com/cenkalti/backoff/v4@v4.3.0/retry.go:88 +0x11c github.com/cenkalti/backoff/v4.RetryNotifyWithTimer(0x263e810?, {0x7f3735ffa130?, 0x17abff29e060?}, 0x17abff29c050?, {0x0?, 0x0?}) github.com/cenkalti/backoff/v4@v4.3.0/retry.go:61 +0x56 github.com/cenkalti/backoff/v4.RetryNotify(...) github.com/cenkalti/backoff/v4@v4.3.0/retry.go:49 github.com/netbirdio/netbird/client/internal/auth.(*Auth).withRetry(0x17abff2aa000, {0x182dd70, 0x17abfef306f0}, 0x17abff0379e0) github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:401 +0x1f0 github.com/netbirdio/netbird/client/internal/auth.(*Auth).Login(0x17abff2aa000, {0x182dd70, 0x17abfef306f0}, {0x7fff13d58d9a, 0x24}, {0x0, 0x0}) github.com/netbirdio/netbird@v0.71.2/client/internal/auth/auth.go:181 +0x130 github.com/netbirdio/netbird/client/embed.(*Client).Start(0x17abfef560c0, {0x182df70, 0x17abff1fa300}) github.com/netbirdio/netbird@v0.71.2/client/embed/embed.go:229 +0x30f main.run({0x182dd38, 0x30e03a0}, {0x176110b, 0x4}, {0x0, 0x0}, {0x0, 0x0}, {0x7fff13d58d9a, 0x24}, ...) github.com/netbirdio/netbird-kubeapi-proxy/main.go:58 +0x24c main.main() github.com/netbirdio/netbird-kubeapi-proxy/main.go:38 +0x325 ``` ### Proposed scope My suggestion is that we refactor the system info logic to use `golang.org/x/sys/unix` instead of shelling out to uname. This does the same thing but makes the underlying system calls instead of calling the binary. A safer result that does not require hard API requirements on output formats to stdout. ### Acceptance criteria Getting system info in Linux should not be dependent on external binaries. ### Additional context _No response_
Author
Owner

@linear-code[bot] commented on GitHub (May 20, 2026):

NET-1195

<!-- gh-comment-id:4500603466 --> @linear-code[bot] commented on GitHub (May 20, 2026): <!-- linear-linkback --> <p><a href="https://linear.app/netbird/issue/NET-1195">NET-1195</a></p>
Author
Owner

@phillebaba commented on GitHub (Jun 1, 2026):

Fixed as #6230 is merged.

<!-- gh-comment-id:4592239059 --> @phillebaba commented on GitHub (Jun 1, 2026): Fixed as #6230 is merged.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#11590