Skip to content

auth: login: explicit check for ipv6 port bindings#1251

Open
svetlyopet wants to merge 1 commit intostackitcloud:mainfrom
svetlyopet:bugfix/auth-flow-port-bind-darwin
Open

auth: login: explicit check for ipv6 port bindings#1251
svetlyopet wants to merge 1 commit intostackitcloud:mainfrom
svetlyopet:bugfix/auth-flow-port-bind-darwin

Conversation

@svetlyopet
Copy link

@svetlyopet svetlyopet commented Jan 23, 2026

Description

Fixes 1250

This PR tries to address the issue of the net.Listen() not being able to see that the requested port is already taken on MacOS.

This happens specifically on MacOS, when there is already a service bound to a port on the IPv6 localhost interface, but the port is free on the IPv4 localhost interface. The net.Listen() method sees that the port is open on the 127.0.0.1 interface, and binds to that one. When the user gets redirected to localhost in the browser, it can redirect to either one of the services using the same port on the different interfaces(seems like localhost resolving to the IPv6 is preferred).

Testing

I tested by running the following python service locally, and executing stackit auth login after that which replicates the issue and can be observed.

#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler
import socket

HOST = "::1"
PORT = 8000

class IPv6HTTPServer(HTTPServer):
    address_family = socket.AF_INET6

server = IPv6HTTPServer((HOST, PORT), SimpleHTTPRequestHandler)
print(f"Serving on http://[{HOST}]:{PORT}")
server.serve_forever()

Checklist

  • Issue was linked above
  • Code format was applied: make fmt
  • Examples were added / adjusted (see e.g. here)
  • Docs are up-to-date: make generate-docs (will be checked by CI)
  • Unit tests got implemented or updated
  • Unit tests are passing: make test (will be checked by CI)
  • No linter issues: make lint (will be checked by CI)

@svetlyopet svetlyopet requested a review from a team as a code owner January 23, 2026 23:41
@github-actions
Copy link

github-actions bot commented Feb 1, 2026

This PR was marked as stale after 7 days of inactivity and will be closed after another 7 days of further inactivity. If this PR should be kept open, just add a comment, remove the stale label or push new commits to it.

@github-actions github-actions bot added the Stale label Feb 1, 2026
@svetlyopet
Copy link
Author

Adding a comment to keep the PR active.

@github-actions github-actions bot removed the Stale label Feb 7, 2026
@github-actions
Copy link

This PR was marked as stale after 7 days of inactivity and will be closed after another 7 days of further inactivity. If this PR should be kept open, just add a comment, remove the stale label or push new commits to it.

Copy link
Contributor

@marceljk marceljk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for you contribution! looks good to me 😃

if ipv6ListenerErr != nil {
continue
}
_ = ipv6Listener.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potential race condition:
If after this line another service binds to [::1]:{port} we have the same situation as before.

@@ -106,7 +112,7 @@ func AuthorizeUser(p *print.Printer, isReauthentication bool) error {
p.Debug(print.DebugLevel, "unable to bind port %d for login redirect: %s", port, listenerErr)
}
if listenerErr != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be extended with a check if ipv6ListenerErr is not nil. It's probably unlikely, but if someone uses already all the ports from 8000-8020, it will continue here without an error and try the authentication flow without an redirect url and the CLI will stop with a panic.

I extended your python code, to simulate this case

#!/usr/bin/env python3
import threading
from http.server import HTTPServer, SimpleHTTPRequestHandler
import socket

HOST = "::1"
PORT = 8000


class IPv6HTTPServer(HTTPServer):
   address_family = socket.AF_INET6

for i in range(0, 21):
   server = IPv6HTTPServer((HOST, PORT + i), SimpleHTTPRequestHandler)
   print(f"Serving on http://[{HOST}]:{PORT+i}")
   t = threading.Thread(target=server.serve_forever)
   t.start()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stackit auth login fails if something already runs on localhost:8000

4 participants