hashicorp/terraform · error

invalid credentials for %s

Error message

invalid credentials for %s

What it means

errUnauthorized() is called on a 401/403; it tries to normalize the final (post-redirect) URL's host with svchostFromURL. If that normalization fails (defensive — the URL was already used for a request) it falls back to this plain error instead of an ErrUnauthorized typed error. So the response was an auth rejection AND the final URL host is unparseable.

Source

Thrown at internal/getproviders/http_mirror_source.go:415

func (s *HTTPMirrorSource) errQueryFailed(provider addrs.Provider, err error) error {
	if err == context.Canceled {
		// This one has a special error type so that callers can
		// handle it in a different way.
		return ErrRequestCanceled{}
	}
	return ErrQueryFailed{
		Provider:  provider,
		Wrapped:   err,
		MirrorURL: s.baseURL,
	}
}

func (s *HTTPMirrorSource) errUnauthorized(finalURL *url.URL) error {
	hostname, err := svchostFromURL(finalURL)
	if err != nil {
		// Again, weird but we'll tolerate it.
		return fmt.Errorf("invalid credentials for %s", finalURL)
	}

	return ErrUnauthorized{
		Hostname: hostname,

		// We can't easily tell from here whether we had credentials or
		// not, so for now we'll just assume we did because "host rejected
		// the given credentials" is, hopefully, still understandable in
		// the event that there were none. (If this ends up being confusing
		// in practice then we'll need to do some refactoring of how
		// we handle credentials in this source.)
		HaveCredentials: true,
	}
}

func svchostFromURL(u *url.URL) (svchost.Hostname, error) {
	raw := u.Host

View on GitHub (pinned to c9def3e214)

Solutions

  1. Provide valid credentials for the mirror host in the CLI config.
  2. Fix the redirect target so the final URL host is a normal DNS name.
  3. Confirm the configured credentials token is current and has not expired.

Example fix

# before: no creds, mirror requires auth
provider_installation { network_mirror { url = "https://mirror.local/tf/" } }

# after
credentials "mirror.local" { token = "$MIRROR_TOKEN" }
provider_installation { network_mirror { url = "https://mirror.local/tf/" } }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure credentials exist and the mirror host normalizes before use.
host, err := svchost.FromURL(mirrorURL)
if err != nil { return fmt.Errorf("mirror host invalid: %w", err) }
if _, err := creds.ForHost(host); err != nil { return err }

Prevention

When it happens

Trigger: Mirror responds 401/403 after redirects to a final URL whose host fails IDNA normalization. Rare, because the request had to succeed enough to get a response; indicates an exotic redirect target or a credentials rejection from an unusual host.

Common situations: Redirect from the mirror to a host with characters IDNA rejects, combined with missing/invalid credentials; credentials helper misconfigured for the redirected host.

Understand the failure class

Related errors


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