{"record":{"id":"b3f0f1be4fb6010b","repo":"hashicorp/terraform","slug":"invalid-credentials-for-s","errorCode":null,"errorMessage":"invalid credentials for %s","messagePattern":"invalid credentials for (.+?)","errorType":"exception","errorClass":"ErrUnauthorized","httpStatus":null,"severity":"error","filePath":"internal/getproviders/http_mirror_source.go","lineNumber":415,"sourceCode":"\nfunc (s *HTTPMirrorSource) errQueryFailed(provider addrs.Provider, err error) error {\n\tif err == context.Canceled {\n\t\t// This one has a special error type so that callers can\n\t\t// handle it in a different way.\n\t\treturn ErrRequestCanceled{}\n\t}\n\treturn ErrQueryFailed{\n\t\tProvider:  provider,\n\t\tWrapped:   err,\n\t\tMirrorURL: s.baseURL,\n\t}\n}\n\nfunc (s *HTTPMirrorSource) errUnauthorized(finalURL *url.URL) error {\n\thostname, err := svchostFromURL(finalURL)\n\tif err != nil {\n\t\t// Again, weird but we'll tolerate it.\n\t\treturn fmt.Errorf(\"invalid credentials for %s\", finalURL)\n\t}\n\n\treturn ErrUnauthorized{\n\t\tHostname: hostname,\n\n\t\t// We can't easily tell from here whether we had credentials or\n\t\t// not, so for now we'll just assume we did because \"host rejected\n\t\t// the given credentials\" is, hopefully, still understandable in\n\t\t// the event that there were none. (If this ends up being confusing\n\t\t// in practice then we'll need to do some refactoring of how\n\t\t// we handle credentials in this source.)\n\t\tHaveCredentials: true,\n\t}\n}\n\nfunc svchostFromURL(u *url.URL) (svchost.Hostname, error) {\n\traw := u.Host\n","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getproviders/http_mirror_source.go#L397-L433","documentation":"`errUnauthorized` tries to derive a `svchost.Hostname` from the final (post-redirect) URL for the `ErrUnauthorized` payload. If that conversion fails — an unusual but tolerated case — it falls back to this plain error message naming the final URL. It is a defensive fallback so the auth-failure path still returns a useful error.","triggerScenarios":"A 401/403 response is being formatted; `svchostFromURL(finalURL)` returns an error; fallback at http_mirror_source.go:415.","commonSituations":"Mirror redirected to a URL with a host `svchost` cannot parse (e.g. an IP literal, an empty host, or an unusual scheme); exotic redirect through a non-DNS hostname.","solutions":["Review the redirect chain (`curl -IL`) that leads to the 401/403 and ensure the final host is a normal DNS hostname.","Configure correct credentials for the mirror hostname.","Avoid mirrors that redirect to IP-literal or otherwise unusual hosts."],"exampleFix":"// before: redirect to IP literal triggers fallback\nhttps://mirror.local -> 302 -> https://10.0.0.1/ -> 401\n// after: mirror serves directly under a DNS hostname\nhttps://mirror.local/hashicorp/aws/index.json -> 401 // still unauthorized,\n// but ErrUnauthorized now carries a real hostname for diagnostics","handlingStrategy":"try-catch","validationCode":"// Pre-validate the final URL host is a service hostname\nif _, err := svchost.FromString(finalURL.Hostname()); err != nil {\n    log.Printf(\"[WARN] final URL host %q not a service hostname; using raw URL in error\", finalURL)\n}","typeGuard":"// finalURLHasValidHost narrows post-redirect URLs\nfunc finalURLHasValidHost(u *url.URL) bool {\n    _, err := svchost.FromString(u.Hostname())\n    return err == nil\n}","tryCatchPattern":"hostname, err := svchostFromURL(finalURL)\nif err != nil {\n    // still return an unauthorized error, just without a structured hostname\n    return ErrUnauthorized{Hostname: \"\", HaveCredentials: true}\n}","preventionTips":["Avoid mirrors that redirect to IP literals or unusual hosts.","Validate redirect targets in the mirror's reverse proxy.","Test the redirect chain with `curl -IL`."],"tags":["network","mirror","authentication","redirect"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}