gohugoio/hugo · error
failed to split baseURL hostport
Error message
failed to split baseURL hostport: %w
What it means
While massaging the baseURL in `fixURL`, when `--appendPort` is enabled and the host already contains a colon, Hugo calls `net.SplitHostPort` to strip any existing port before re-appending the server port. This wraps a `SplitHostPort` failure, indicating the host segment is malformed (e.g. too many colons without brackets).
Solutions
- Use bracketed IPv6 in the baseURL, e.g. `http://[::1]:1313/`.
- Simplify the baseURL to a clean host without an embedded port (Hugo appends the server port itself).
- If you truly need a fixed port in baseURL, set `appendPort = false` in `hugo.toml`.
Example fix
// before baseURL = "http://::1/" // after baseURL = "http://[::1]/"
Defensive patterns
Strategy: validation
Validate before calling
import "net/url"
import "net"
func validateBaseURLHost(rawBaseURL string, appendPort bool) error {
if !appendPort { return nil }
u, err := url.Parse(rawBaseURL)
if err != nil { return err }
if strings.Contains(u.Host, ":") {
if _, _, err := net.SplitHostPort(u.Host); err != nil {
return fmt.Errorf("malformed host %q: %w", u.Host, err)
}
}
return nil
} Type guard
null
Try / catch
// If the baseURL host can't be split, fall back to a clean host
// without an embedded port and let Hugo append its server port.
if _, _, err := net.SplitHostPort(u.Host); err != nil {
// strip the port portion or use a bracketed IPv6 form
} Prevention
- Bracket IPv6 literals in baseURL: `http://[::1]/`.
- Don't embed a custom port in baseURL when `appendPort` is true (Hugo manages the port).
- Set `appendPort = false` if you need to pin a port inside baseURL.
When it happens
Trigger: Fires when `serverAppend` is true, the parsed baseURL host contains `:`, and `net.SplitHostPort(u.Host)` errors — for example an IPv6 address without brackets, or a host like `host:port:extra`.
Common situations: Setting a `baseURL` to an IPv6 literal without square brackets (`http://::1/`); a malformed `--baseURL` with multiple colons; a config migrated from another tool that produced a non-RFC host string.
Related errors
- failed to create baseURL from
- server startup failed
- unable to find alternative port to use
- --appendPort=false not supported when in multihost mode
- cannot use --renderToMemory with --destination
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/20ed961a6eae6a11.
Report an issue: GitHub.
Appendix: source
Thrown at commands/server.go:838
if err != nil {
return "", err
}
}
if useLocalhost {
if certsSet {
u.Scheme = "https"
} else if u.Scheme == "https" {
u.Scheme = "http"
}
u.Host = "localhost"
}
if c.serverAppend {
if strings.Contains(u.Host, ":") {
u.Host, _, err = net.SplitHostPort(u.Host)
if err != nil {
return "", fmt.Errorf("failed to split baseURL hostport: %w", err)
}
}
u.Host += fmt.Sprintf(":%d", port)
}
return u.String(), nil
}
func (c *serverCommand) partialReRender(urls ...string) (err error) {
defer func() {
c.errState.setWasErr(false)
}()
visited := types.NewEvictingQueue[string](len(urls))
for _, url := range urls {
visited.Add(url)
}
var h *hugolib.HugoSitesView on GitHub (pinned to 52c9bd7908)