AdguardTeam/AdGuardHome · error

invalid upstream servers: %w

Error message

invalid upstream servers: %w

What it means

Validation error raised while adding or updating a persistent client: the client's Upstreams strings could not be parsed into valid upstream server configs. The underlying proxy.ParseUpstreamsConfig error is wrapped, so the cause (bad URL, unsupported scheme, bad port) is visible in the chain.

Source

Thrown at internal/client/persistent.go:150

}

// validate returns an error if persistent client information contains errors.
// allTags must be sorted.
func (c *Persistent) validate(ctx context.Context, l *slog.Logger, allTags []string) (err error) {
	switch {
	case c.Name == "":
		return errors.Error("empty name")
	case c.idendifiersLen() == 0:
		return errors.Error("id required")
	case c.UID == UID{}:
		return errors.Error("uid required")
	}

	conf, err := proxy.ParseUpstreamsConfig(c.Upstreams, &upstream.Options{
		Logger: l.With(aghslog.KeyUpstreamType, aghslog.UpstreamTypeTest),
	})
	if err != nil {
		return fmt.Errorf("invalid upstream servers: %w", err)
	}

	err = conf.Close()
	if err != nil {
		l.ErrorContext(ctx, "client: closing upstream config", slogutil.KeyError, err)
	}

	for _, t := range c.Tags {
		_, ok := slices.BinarySearch(allTags, t)
		if !ok {
			return fmt.Errorf("invalid tag: %q", t)
		}
	}

	// TODO(s.chzhen):  Move to the constructor.
	slices.Sort(c.Tags)

	return nil

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Read the wrapped cause in the error chain to identify the offending upstream string
  2. Fix the URL: valid scheme (dns://, https://, tcp://, quic://, tls://) and correct host:port
  3. Test the upstream string with proxy.ParseUpstreamsConfig directly before calling Add

Example fix

// before
c.Upstreams = []string{"dns.example.com"} // missing scheme/port

// after
c.Upstreams = []string{"dns://dns.example.com:53"}
Defensive patterns

Strategy: validation

Validate before calling

_, err := proxy.ParseUpstreamsConfig(c.Upstreams, &upstream.Options{Logger: testLogger})
if err != nil { /* reject before Add/Update */ }

Try / catch

if err := s.Add(ctx, c); err != nil && strings.Contains(err.Error(), "invalid upstream servers") { /* surface wrapped cause to user for correction */ }

Prevention

When it happens

Trigger: Calling Storage.Add or Storage.Update with c.Upstreams containing an invalid upstream spec, e.g. "[::1]:bad", "htp://example.com", or a malformed dns:// URL.

Common situations: Typos in per-client upstream strings, using a scheme the proxy package doesn't support, missing port on non-default schemes, trailing whitespace or quotes after YAML editing.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/c642b55ec9995f08. Report an issue: GitHub.