nats-io/nats-server · error

error parsing %s url [%q]

Error message

error parsing %s url [%q]

What it means

parseURL in server/opts.go wraps url.Parse failures for typed URLs (monitor/cluster/gateway/auth URLs; typ names the kind). If the string is not even a well-formed URL, the library logs it as-is — including possible credentials — because there is no sane way to redact an unparseable URL. The error names the URL type and the raw string in %q.

Source

Thrown at server/opts.go:2269

		dd[sURL] = true
		url, err := parseURL(sURL, typ)
		if err != nil {
			err := &configErr{tk, err.Error()}
			errors = append(errors, err)
			continue
		}
		urls = append(urls, url)
	}
	return urls, errors
}

func parseURL(u string, typ string) (*url.URL, error) {
	urlStr := strings.TrimSpace(u)
	url, err := url.Parse(urlStr)
	if err != nil {
		// Security note: if it's not well-formed but still reached us, then we're going to log as-is which might include password information here.
		// If the URL parses, we don't log the credentials ever, but if it doesn't even parse we don't have a sane way to redact.
		return nil, fmt.Errorf("error parsing %s url [%q]", typ, urlStr)
	}
	return url, nil
}

func parseGateway(v any, o *Options, errors *[]error, warnings *[]error) error {
	var lt token
	defer convertPanicToErrorList(&lt, errors)

	tk, v := unwrapValue(v, &lt)
	gm, ok := v.(map[string]any)
	if !ok {
		return &configErr{tk, fmt.Sprintf("Expected gateway to be a map, got %T", v)}
	}
	for mk, mv := range gm {
		// Again, unwrap token value if line check is required.
		tk, mv = unwrapValue(mv, &lt)
		switch strings.ToLower(mk) {
		case "name":

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Fix the URL syntax named in the error; note the raw string may contain a password, so rotate any credentials visible in logs.
  2. Percent-encode special characters in embedded passwords (url.QueryEscape/PathEscape).
  3. Remove whitespace/control characters, especially from env-substituted values.
  4. Test the string with url.Parse (or an equivalent validator) offline before putting it into the config.

Example fix

// before
url: "http://user:p@ss%zz@localhost:8222"
// after
url: "http://user:p%40ss@localhost:8222"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(rawURL))
if err != nil {
	return fmt.Errorf("rejecting malformed %s url before server start: %v", typ, err)
}

Prevention

When it happens

Trigger: Any config URL option (client_advertise, gateway/cluster/auth URLs) containing control characters, spaces, invalid percent-encoding ('%zz'), or other text url.Parse rejects.

Common situations: Typos like 'http//host:8222' (missing colon); unescaped special characters in passwords embedded in URLs; newline/space from env substitution; accidental shell-style placeholders.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/9ec0fcf1dec7a987. Report an issue: GitHub.