hashicorp/terraform · error
response has invalid Content-Type
Error message
response has invalid Content-Type: %s
What it means
For a 200 response, the client parses the `Content-Type` header with `mime.ParseMediaType`. If the header value is malformed (e.g. unparseable parameters, stray characters), the parse error is surfaced. This is distinct from a wrong-but-well-formed media type.
Solutions
- Capture the raw `Content-Type` header with `curl -i` and inspect it.
- Fix the mirror server / reverse proxy to emit a clean `Content-Type: application/json`.
- Remove any middleware that rewrites headers incorrectly.
Example fix
// before Content-Type: application/json; charset= // after Content-Type: application/json
Defensive patterns
Strategy: validation
Validate before calling
// Validate Content-Type well-formedness before sending the response
ct := resp.Header.Get("Content-Type")
if _, _, err := mime.ParseMediaType(ct); err != nil {
return fmt.Errorf("mirror sent malformed Content-Type %q: %w", ct, err)
} Type guard
// isValidContentType narrows to parseable header values
func isValidContentType(ct string) bool {
_, _, err := mime.ParseMediaType(ct)
return err == nil
} Prevention
- Configure the mirror to emit a clean `Content-Type: application/json`.
- Avoid header-rewriting middleware.
- Audit reverse-proxy config for stray header edits.
- Smoke-test headers with `curl -i`.
When it happens
Trigger: `mime.ParseMediaType(ct)` returns an error for the response's `Content-Type` header; error at http_mirror_source.go:377.
Common situations: Mirror/proxy sends a malformed `Content-Type` (missing closing quote, illegal chars); custom header injection by an intermediary; rare misconfigured CDN.
Related errors
- response has invalid Content-Type: must be application/json
- failed to determine request credentials
- invalid credentials for
- invalid provider mirror base URL
- invalid response content from mirror server
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/fe755b697b100e15.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getproviders/http_mirror_source.go:377
defer func() {
// If we're not returning the body then we'll close it
// before we return.
if body == nil {
resp.Body.Close()
}
}()
// After this point, our final URL return value should always be the
// one from resp.Request, because that takes into account any redirects
// we followed along the way.
finalURL = resp.Request.URL
if resp.StatusCode == http.StatusOK {
// If and only if we get an OK response, we'll check that the response
// type is JSON and return the body reader.
ct := resp.Header.Get("Content-Type")
mt, params, err := mime.ParseMediaType(ct)
if err != nil {
return 0, nil, finalURL, fmt.Errorf("response has invalid Content-Type: %s", err)
}
if mt != "application/json" {
return 0, nil, finalURL, fmt.Errorf("response has invalid Content-Type: must be application/json")
}
for name := range params {
// The application/json content-type has no defined parameters,
// but some servers are configured to include a redundant "charset"
// parameter anyway, presumably out of a sense of completeness.
// We'll ignore them but warn that we're ignoring them in case the
// subsequent parsing fails due to the server trying to use an
// unsupported character encoding. (RFC 7159 defines its own
// JSON-specific character encoding rules.)
log.Printf("[WARN] Network mirror returned %q as part of its JSON content type, which is not defined. Ignoring.", name)
}
body = resp.Body
}
return resp.StatusCode, body, finalURL, nilView on GitHub (pinned to d32a084675)