coredns/coredns · error
paths are not allowed in HTTPS upstream addresses (the /dns-
Error message
paths are not allowed in HTTPS upstream addresses (the /dns-query path is used by default): %s
What it means
The forward plugin's DoH implementation always uses the default /dns-query path, so HTTPS upstream addresses containing a path are rejected at setup. parseStanza iterates the TO addresses, and any address whose transport is HTTPS with a '/' in the host part triggers this error.
Source
Thrown at plugin/forward/setup.go:166
return f, c.ArgErr()
}
// Parse block first to get resolver and other options before processing TO addresses.
for c.NextBlock() {
if err := parseBlock(c, f); err != nil {
return f, err
}
}
if f.maxAge > 0 && f.maxAge < f.expire {
return f, fmt.Errorf("max_age (%s) must not be less than expire (%s)", f.maxAge, f.expire)
}
// Reject HTTPS upstreams that include a path, the doh implementation default to /dns-query path.
for _, addr := range to {
trans, h := parse.Transport(addr)
if trans == transport.HTTPS && strings.Contains(h, "/") {
return f, fmt.Errorf("paths are not allowed in HTTPS upstream addresses (the /dns-query path is used by default): %s", addr)
}
}
// Classify TO addresses in order, preserving config ordering.
entries, err := classifyToAddrs(to)
if err != nil {
return f, err
}
f.toEntries = entries
// Expand hostnames and deduplicate globally (first-seen order wins).
toHosts, err := expandAndDedup(f.toEntries, f.resolver)
if err != nil {
return f, err
}
if len(toHosts) == 0 {
return f, fmt.Errorf("no valid upstream addresses found")
}View on GitHub (pinned to 558c9757a9)
Solutions
- Strip the path from the HTTPS upstream address, keeping only https://host[:port].
- Rely on the plugin's built-in /dns-query default path.
- If the provider uses a non-standard path, put a local reverse proxy in front and forward to it without a path.
Example fix
// before forward . https://cloudflare-dns.com/dns-query // after forward . https://cloudflare-dns.com
Defensive patterns
Strategy: validation
Validate before calling
u, _ := url.Parse(upstream)
if u.Scheme == "https" && (u.Path != "" && u.Path != "/") {
return fmt.Errorf("strip path from DoH upstream: %s", upstream)
} Prevention
- Store DoH upstreams as bare https://host values, not endpoint URLs.
- Trim paths in config pipelines that ingest provider endpoint URLs.
When it happens
Trigger: Corefile 'forward . https://dns.example.com/dns-query' or any https:// upstream with a trailing/extra path component.
Common situations: Copying a DoH URL (with path) from a browser or provider docs into the Corefile; templating the provider's full endpoint URL; confusion between RFC8484 endpoint URLs and CoreDNS's simplified https://host syntax.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- no forwarder defined
- this plugin can only be used once per Server Block
- more than %d TOs configured: %d
- unable to normalize '%s'
- max_age (%s) must not be less than expire (%s)
AI-assisted analysis of coredns/coredns@558c9757a9 (2026-09-06).
Data as JSON: /api/errors/a9705c60b6dae694.
Report an issue: GitHub.