netbirdio/netbird · error
expose service: %v
Error message
expose service: %v
What it means
The initial client.ExposeService RPC was rejected by the daemon; the gRPC status message is surfaced. By this point every flag passed validateExposeFlags, the daemon connection was live, and the request (port, protocol enum, pin/password/user-groups, domain, name prefix, and ListenPort for L4) had been sent — so the failure is a daemon-side or management-side refusal, not a CLI validation issue.
Source
Thrown at client/cmd/expose.go:205
return err
}
req := &proto.ExposeServiceRequest{
Port: uint32(port),
Protocol: protocol,
Pin: exposePin,
Password: exposePassword,
UserGroups: exposeUserGroups,
Domain: exposeDomain,
NamePrefix: exposeNamePrefix,
}
if isClusterProtocol(exposeProtocol) {
req.ListenPort = uint32(resolveExternalPort(port))
}
stream, err := client.ExposeService(ctx, req)
if err != nil {
return fmt.Errorf("expose service: %v", status.Convert(err).Message())
}
if err := handleExposeReady(cmd, stream, port); err != nil {
return err
}
return waitForExposeEvents(cmd, ctx, stream)
}
func toExposeProtocol(exposeProtocol string) (proto.ExposeProtocol, error) {
p, err := expose.ParseProtocolType(exposeProtocol)
if err != nil {
return 0, fmt.Errorf("invalid protocol: %w", err)
}
switch p {
case expose.ProtocolHTTP:
return proto.ExposeProtocol_EXPOSE_HTTP, nilView on GitHub (pinned to 93e97f4bf1)
Solutions
- Make sure the peer is connected first: `netbird status` must show Connected; run `netbird up` and wait, then retry
- Confirm your management/account supports exposed services (cloud feature flag or self-hosted management version) and that it is enabled for the account
- If using --with-custom-domain, verify the domain is added and verified for your account in the dashboard, or drop the flag to get an assigned domain
- Re-run with the daemon at debug log level and read its log at the failure timestamp for the exact refusal reason
Defensive patterns
Strategy: try-catch
Validate before calling
# require a healthy, connected peer before exposing
netbird status --check live || { echo 'peer not connected; run netbird up first'; exit 1; } Try / catch
stream, err := client.ExposeService(ctx, req)
if err != nil {
msg := status.Convert(err).Message()
switch status.Code(err) {
case codes.FailedPrecondition:
// peer not connected/logged in: bring it up, then retry
return fmt.Errorf("expose service: connect the peer first (netbird up): %s", msg)
case codes.InvalidArgument:
// server-side validation (domain, name prefix): fix the flags
return fmt.Errorf("expose service: invalid request (%s); check --with-custom-domain/--with-name-prefix", msg)
default:
return fmt.Errorf("expose service: %s", msg)
}
} Prevention
- Run `netbird up` and confirm Connected in `netbird status` before exposing anything
- Verify the management account supports services/expose before scripting around it
- Only pass --with-custom-domain with a domain already configured and verified in the dashboard
- Capture the daemon log when the status message is vague — the daemon logs the refusal reason
When it happens
Trigger: The peer is not connected or not logged in, so the daemon refuses to create an exposed service; the management plane does not support the services feature; a --with-custom-domain value that is not configured on the account; server-side validation rejecting name prefix or domain; the expose subsystem on the daemon not being ready; the context canceled before the RPC was sent.
Common situations: Running `netbird expose` before `netbird up` has finished connecting; self-hosted management older than the services feature; assuming any domain string works with --with-custom-domain; running against a management account where the reverse-proxy feature is disabled.
Related errors
- failed to get status: %v
- failed to get log level: %v
- failed to set log level to TRACE: %v
- failed to set sync response persistence: %v
- connect to daemon: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/5b85ff8b84100227.
Report an issue: GitHub.