MHSanaei/3x-ui · error

node port must be 1-65535

Error message

node port must be 1-65535

What it means

The node health probe validates n.Port before constructing the status URL (/panel/api/server/status) and rejects ports outside 1-65535. The value is written into patch.LastError so the node list UI shows it inline. Zero is the common case — a node saved without a port — and out-of-range values usually come from bad config sync or manual API writes.

Source

Thrown at internal/web/service/node.go:1115

	fn(proxyURL)
}

func (s *NodeService) probe(ctx context.Context, n *model.Node, proxyURL string) (HeartbeatPatch, error) {
	patch := HeartbeatPatch{LastHeartbeat: time.Now().Unix()}

	addr, err := netsafe.NormalizeHost(n.Address)
	if err != nil {
		patch.LastError = err.Error()
		return patch, err
	}
	scheme := n.Scheme
	if scheme != "http" && scheme != "https" {
		scheme = "https"
	}
	if n.Port <= 0 || n.Port > 65535 {
		patch.LastError = "node port must be 1-65535"
		return patch, errors.New(patch.LastError)
	}
	probeURL := &url.URL{
		Scheme: scheme,
		Host:   net.JoinHostPort(addr, strconv.Itoa(n.Port)),
		Path:   normalizeBasePath(n.BasePath) + "panel/api/server/status",
	}

	req, err := http.NewRequestWithContext(
		netsafe.ContextWithAllowPrivate(ctx, n.AllowPrivateAddress),
		http.MethodGet, probeURL.String(), nil)
	if err != nil {
		patch.LastError = err.Error()
		return patch, err
	}
	if n.ApiToken != "" {
		req.Header.Set("Authorization", "Bearer "+n.ApiToken)
	}
	req.Header.Set("Accept", "application/json")

View on GitHub (pinned to ad32144c42)

Solutions

  1. Set a valid port (the remote panel's HTTPS port, e.g. 443 or 2053) on the node and save
  2. Validate port in range before creating nodes from scripts
  3. If it recurs, audit what writes the nodes table / sync payload for the port field

Example fix

// before
node.Port = 0 // omitted in payload

// after
port, err := strconv.Atoi(rawPort)
if err != nil || port < 1 || port > 65535 {
    return fmt.Errorf("invalid node port %q", rawPort)
}
node.Port = port
Defensive patterns

Strategy: validation

Validate before calling

if node.Port < 1 || node.Port > 65535 {
    return fmt.Errorf("node %s: port %d out of range", node.Name, node.Port)
}

Prevention

When it happens

Trigger: Adding a node via the API with port omitted (Go zero-value 0); a port string like '8443 ' parsed to 0; synced node data with a corrupted port field.

Common situations: Automation creating nodes without the port field; editing nodes directly in the DB; YAML/JSON config with port as string that coerced badly.

Related errors


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/84aebe92935331c3. Report an issue: GitHub.