hashicorp/terraform · error

invalid provider mirror base URL

Error message

invalid provider mirror base URL %s: %s

What it means

`mirrorHostCredentials` calls `mirrorHost()` to derive a `svchost.Hostname` from the mirror base URL. If that conversion fails (URL not parseable into a valid hostname), the error wraps the cause and names the base URL.

Solutions

  1. Validate the `network_mirror` URL in the CLI config (`~/.terraformrc` or `terraform.rc`): it must be a well-formed `https://hostname/...` URL.
  2. Use an IP or hostname that `svchost.Hostname` can parse (no spaces, valid DNS chars).
  3. Restart Terraform after fixing the config.

Example fix

// before
provider_installation {
  network_mirror { url = "https:///mirror.local/" } // empty host
}
// after
provider_installation {
  network_mirror { url = "https://mirror.local/" }
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the configured mirror URL up front
u, err := url.Parse(mirrorURL)
if err != nil || u.Host == "" {
    return fmt.Errorf("network_mirror.url %q has no usable host", mirrorURL)
}
if _, err := svchost.FromString(u.Hostname()); err != nil {
    return fmt.Errorf("network_mirror.url host %q is not a valid service hostname", u.Hostname())
}

Type guard

// isValidMirrorURL narrows to URLs whose host svchost accepts
func isValidMirrorURL(s string) bool {
    u, err := url.Parse(s)
    if err != nil || u.Host == "" { return false }
    _, err = svchost.FromString(u.Hostname())
    return err == nil
}

Prevention

When it happens

Trigger: `svchostFromURL(s.baseURL)` returns an error inside `mirrorHostCredentials`; error at http_mirror_source.go:304.

Common situations: `network_mirror.url` configured with a URL whose host is empty or invalid; URL using a scheme/host combination `svchost` rejects; runtime mutation of `baseURL` to something invalid.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/d8afd0ef616061dc. Report an issue: GitHub.

Appendix: source

Thrown at internal/getproviders/http_mirror_source.go:304

//
// If the returned error is non-nil then the given hostname doesn't comply
// with the IETF RFC 5891 section 5.3 and 5.4 validation rules, and thus cannot
// be interpreted as a valid Terraform service host. The IDNA validation errors
// are unfortunately usually not very user-friendly, but they are also
// relatively rare because the IDNA normalization rules are quite tolerant.
func (s *HTTPMirrorSource) mirrorHost() (svchost.Hostname, error) {
	return svchostFromURL(s.baseURL)
}

// mirrorHostCredentials returns the HostCredentials, if any, for the hostname
// included in the mirror base URL.
//
// It might return an error if the mirror base URL is invalid, or if the
// credentials lookup itself fails.
func (s *HTTPMirrorSource) mirrorHostCredentials() (svcauth.HostCredentials, error) {
	hostname, err := s.mirrorHost()
	if err != nil {
		return nil, fmt.Errorf("invalid provider mirror base URL %s: %s", s.baseURL.String(), err)
	}

	if s.creds == nil {
		// No host-specific credentials, then.
		return nil, nil
	}

	return s.creds.ForHost(hostname)
}

// get is the shared functionality for querying a JSON index from a mirror.
//
// It only handles the raw HTTP request. The "body" return value is the
// reader from the response if and only if the response status code is 200 OK
// and the Content-Type is application/json. In all other cases it's nil.
// If body is non-nil then the caller must close it after reading it.
//
// If the "finalURL" return value is not empty then it's the URL that actually

View on GitHub (pinned to d32a084675)