ginuerzh/gost · error

ErrInvalidNode

ErrInvalidNode

Error message

invalid node

What it means

ErrInvalidNode is the sentinel error returned by ParseNode when the input string, after trimming whitespace, is empty. A proxy Node must at minimum have a non-empty address string; an empty input cannot form a valid node for a proxy chain.

Source

Thrown at node.go:15

package gost

import (
	"errors"
	"fmt"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	// ErrInvalidNode is an error that implies the node is invalid.
	ErrInvalidNode = errors.New("invalid node")
)

// Node is a proxy node, mainly used to construct a proxy chain.
type Node struct {
	ID               int
	Addr             string
	Host             string
	Protocol         string
	Transport        string
	Remote           string   // remote address, used by tcp/udp port forwarding
	url              *url.URL // raw url
	User             *url.Userinfo
	Values           url.Values
	DialOptions      []DialOption
	HandshakeOptions []HandshakeOption
	ConnectOptions   []ConnectOption
	Client           *Client
	marker           *failMarker

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Trim and skip empty entries before calling ParseNode when parsing node lists.
  2. Provide a valid non-empty node string (scheme://host:port) from config or env.
  3. Validate required address fields at startup and fail fast with a clear message.
  4. Check errors.Is(err, gost.ErrInvalidNode) to distinguish empty input from malformed-URL parse failures.

Example fix

// before
node, err := ParseNode(cfg.Proxy) // "" -> ErrInvalidNode
// after
s := strings.TrimSpace(cfg.Proxy)
if s == "" {
    return fmt.Errorf("proxy address is required")
}
node, err := ParseNode(s)
Defensive patterns

Strategy: validation

Validate before calling

s := strings.TrimSpace(input)
if s == "" {
	return fmt.Errorf("node address must be a non-empty string")
}
node, err := gost.ParseNode(s)
if err != nil {
	return fmt.Errorf("parse node %q: %w", s, err)
}

Type guard

func isValidNodeInput(s string) bool {
	return strings.TrimSpace(s) != ""
}

Try / catch

node, err := gost.ParseNode(input)
if err != nil {
	if errors.Is(err, gost.ErrInvalidNode) {
		return fmt.Errorf("empty node input %q", input)
	}
	return err
}

Prevention

When it happens

Trigger: Calling gost.ParseNode("") or ParseNode with a string containing only whitespace (spaces, tabs, newlines); passing an unconfigured config field (e.g. empty peer address) into ParseNode.

Common situations: Environment variables or config files with missing/blank proxy URLs; splitting a comma-separated node list that contains empty entries (e.g. "a:8080,,b:8080"); template placeholders left unfilled.

Related errors


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/61cf1c399efe5d59. Report an issue: GitHub.