-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Description
When connecting to a NetBird management server behind a GKE Gateway (Google Kubernetes Engine Gateway API), native clients fail with:
retrying Login to the Management service in 1.102599784s due to error rpc error: code = Unknown desc = getting device authorization flow info failed with error: failed while getting Management Service public key
Extended debugging reveals the underlying gRPC error:
GRPC_GO_LOG_VERBOSITY_LEVEL=99 GRPC_GO_LOG_SEVERITY_LEVEL=info sudo netbird up -F -l debug --management-url https://nb-api.example.com2026-01-10T17:07:08+01:00 DEBG client/net/dialer_dial.go:20: Dialing tcp nb-api.example.com:443
2026-01-10T17:07:09+01:00 DEBG client/internal/login.go:65: connected to the Management service https://nb-api.example.com:443
2026-01-10T17:07:09+01:00 ERRO shared/management/client/grpc.go:282: failed while getting Management Service public key: rpc error: code = Unimplemented desc = fault filter abort
2026-01-10T17:07:09+01:00 ERRO client/internal/login.go:111: failed while getting Management Service public key: failed while getting Management Service public key
2026-01-10T17:07:09+01:00 WARN client/cmd/root.go:248: retrying Login to the Management service in 963.390646ms due to error failed while getting Management Service public key
Root Cause
The NetBird gRPC client sends the :authority HTTP/2 pseudo-header with the port included (e.g., nb-api.example.com:443), but GKE Gateway's HTTPRoute only matches hostnames without ports (e.g., nb-api.example.com). This causes the gateway to reject the request with "fault filter abort".
Evidence
Testing with grpcurl reproduces the issue:
# Fails - sends :authority with port
$ grpcurl -proto management.proto nb-api.example.com:443 management.ManagementService/GetServerKey
ERROR: Code: Unimplemented, Message: fault filter abort
# Works - explicit authority without port
$ grpcurl -authority nb-api.example.com -proto management.proto nb-api.example.com:443 management.ManagementService/GetServerKey
{
"key": "...",
"expiresAt": ...
}Additionally, curl (which sends :authority without port) works correctly:
$ curl --http2 -X POST -H "Content-Type: application/grpc" https://nb-api.example.com/management.ManagementService/GetServerKey
# Returns grpc-status: 2 (expected for empty request body)Direct connection via kubectl port-forward (bypassing the gateway) works perfectly, confirming the management server itself is correctly configured.
Environment
- Deployment: Self-hosted NetBird on GKE
- Gateway: GKE Gateway API with
gke-l7-regional-external-managedgateway class - NetBird version: latest (netbirdio/management:latest)
- Client: Native macOS client
- Protocol: gRPC over HTTPS (TLS termination at gateway, re-encryption to backend)
Expected Behavior
The gRPC client should send the :authority header without the port when connecting to standard HTTPS port 443, matching the behavior of other HTTP/2 clients like curl.