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 nilView on GitHub (pinned to b41aefbe51)
Solutions
- Read the wrapped cause in the error chain to identify the offending upstream string
- Fix the URL: valid scheme (dns://, https://, tcp://, quic://, tls://) and correct host:port
- 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
- Always include scheme and port: dns://host:53, https://host:443
- Validate upstream strings with ParseUpstreamsConfig in form handlers before persisting
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
- dns.bind_hosts at index %d is not a valid ip address
- json time is nil
- networksetup failed to set dns servers: %w
- found no dns servers in %s
- writing conf: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/c642b55ec9995f08.
Report an issue: GitHub.