gohugoio/hugo · error

failed to create baseURL from %q: %s

Error message

failed to create baseURL from %q: %s

What it means

When starting the server, Hugo rewrites each language's baseURL for local serving (`fixURL`) and then constructs a `urls.BaseURL` from the result. If `urls.NewBaseURLFromString` cannot parse the massaged URL string, server startup aborts with this error, showing the offending string and the underlying parse error.

Source

Thrown at commands/server.go:651

		panic("no server ports set")
	}
	return c.withConfE(func(conf *commonConfig) error {
		for i, language := range conf.configs.Languages {
			isMultihost := conf.configs.IsMultihost
			var serverPort int
			if isMultihost {
				serverPort = c.serverPorts[i].p
			} else {
				serverPort = c.serverPorts[0].p
			}
			langConfig := conf.configs.LanguageConfigMap[language.Lang]
			baseURLStr, err := c.fixURL(langConfig.BaseURL, c.r.baseURL, serverPort)
			if err != nil {
				return err
			}
			baseURL, err := urls.NewBaseURLFromString(baseURLStr)
			if err != nil {
				return fmt.Errorf("failed to create baseURL from %q: %s", baseURLStr, err)
			}

			baseURLLiveReload := baseURL
			if c.liveReloadPort != -1 {
				baseURLLiveReload, _ = baseURLLiveReload.WithPort(c.liveReloadPort)
			}
			langConfig.C.SetServerInfo(baseURL, baseURLLiveReload, c.serverInterface)

		}
		return nil
	})
}

func (c *serverCommand) getErrorWithContext() any {
	buildErr := c.errState.buildErr()
	if buildErr == nil {
		return nil
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Check `baseURL` in your config (and per-language overrides) for typos, spaces, or invalid characters; use a full URL like `https://example.org/`.
  2. Verify any `--baseURL` flag or env-var substitution in CI actually expands to a valid URL.
  3. In multilingual/multihost sites, validate every language's `baseURL`, since each is processed here.
  4. Temporarily run without `-b` to isolate whether the config or the flag is at fault.

Example fix

# before (hugo.toml)
baseURL = "example com/blog"
# after
baseURL = "https://example.com/blog/"
Defensive patterns

Strategy: validation

Validate before calling

if _, err := url.Parse(baseURL); err != nil || baseURL == "" {
    return fmt.Errorf("invalid baseURL %q: %v", baseURL, err)
}

Prevention

When it happens

Trigger: A malformed `baseURL` in the site/language config or an invalid `--baseURL`/`-b` flag value — e.g. containing spaces, illegal characters, a bad scheme, or an unparsable host — that survives `fixURL`'s best-effort `//`-prefixing but fails `url.Parse`/BaseURL validation.

Common situations: Typos in `hugo.toml` baseURL (`htp://`, stray quotes, spaces); templated baseURLs from CI env vars that expand empty or with newlines; per-language `baseURL` overrides in multilingual configs; passing a path-only or exotic value to `-b`.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/463dd1403ded3723.json. Report an issue: GitHub ↗.