caddyserver/caddy · error
invalid admin address %s: %v
Error message
invalid admin address %s: %v
What it means
Thrown by AdminAPIRequest when the admin endpoint address passed to the CLI cannot be parsed by caddy.ParseNetworkAddress, or when it expands to more than one port. The address must be a single, well-formed network address such as 'localhost:2019', '127.0.0.1:2019', or 'unix//run/caddy/admin.sock'. Any parse error is wrapped into this message along with the offending address.
Source
Thrown at cmd/commandfuncs.go:777
for _, envfile := range envfileFlag {
if err := loadEnvFromFile(envfile); err != nil {
return fmt.Errorf("loading additional environment variables: %v", err)
}
}
return nil
}
// AdminAPIRequest makes an API request according to the CLI flags given,
// with the given HTTP method and request URI. If body is non-nil, it will
// be assumed to be Content-Type application/json. The caller should close
// the response body. Should only be used by Caddy CLI commands which
// need to interact with a running instance of Caddy via the admin API.
func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io.Reader) (*http.Response, error) {
parsedAddr, err := caddy.ParseNetworkAddress(adminAddr)
if err != nil || parsedAddr.PortRangeSize() > 1 {
return nil, fmt.Errorf("invalid admin address %s: %v", adminAddr, err)
}
origin := "http://" + parsedAddr.JoinHostPort(0)
if parsedAddr.IsUnixNetwork() {
origin = "http://127.0.0.1" // bogus host is a hack so that http.NewRequest() is happy
// the unix address at this point might still contain the optional
// unix socket permissions, which are part of the address/host.
// those need to be removed first, as they aren't part of the
// resulting unix file path
addr, _, err := internal.SplitUnixSocketPermissionsBits(parsedAddr.Host)
if err != nil {
return nil, err
}
parsedAddr.Host = addr
} else if parsedAddr.IsFdNetwork() {
origin = "http://127.0.0.1"
}
View on GitHub (pinned to 50e54ee279)
Solutions
- Pass a plain host:port without a scheme, e.g. --address localhost:2019
- Remove any port range; the admin endpoint must be exactly one port
- For unix sockets use the unix/ prefix, e.g. unix//run/caddy/admin.sock
- If the address comes from the config, fix the admin.listen value and reload
Example fix
# before caddy reload --address http://localhost:2019 # after caddy reload --address localhost:2019
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking commands that hit the admin API, confirm the address parses
// to exactly one port:
addr, err := caddy.ParseNetworkAddress(adminAddr)
if err != nil || addr.PortRangeSize() > 1 {
return fmt.Errorf("admin address %q must be a single host:port (no scheme, no port range)", adminAddr)
} Prevention
- Never prefix the admin address with http:// or https://
- Keep admin.listen a single port in configs consumed by the CLI
- Omit --address and let Caddy read admin.listen from the config
When it happens
Trigger: Calling any CLI command that talks to the admin API (reload, stop, list-modules, adapt via API, etc.) with --address set to a malformed value: empty host with bad port ('localhost:'), a port range like 'localhost:2019-2020', an unknown network prefix, or a stray scheme like 'http://localhost:2019'.
Common situations: Users prefixing http:// to the admin address (it is not a URL), copying a port range from a site address into the admin listen, or setting the admin listen in the config to a multi-port range and then running 'caddy reload --address ...'.
Related errors
- caddy responded with error: HTTP %d: %s
- no config file to load; either use --config flag or ensure C
- no metrics registry found
- loading identity issuer modules: %s
- access control %d public key %d: parsing base64 certificate
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/774008be2cfb41be.
Report an issue: GitHub.