hashicorp/terraform · error

response has invalid Content-Type: %s

Error message

response has invalid Content-Type: %s

What it means

On a 200 response, get() reads the Content-Type header and runs mime.ParseMediaType on it. If the header value is structurally malformed (unparseable by the MIME parser) this error is returned directly (not wrapped in ErrQueryFailed). It indicates the mirror sent a broken Content-Type header on a successful response.

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, nil

View on GitHub (pinned to c9def3e214)

Solutions

  1. Check the response headers with curl -i and inspect Content-Type.
  2. Set Content-Type to exactly application/json with no malformed parameters.
  3. If a charset parameter is needed, ensure it is properly formatted (charset=utf-8).

Example fix

# before
Content-Type: application/json; charset="utf-8"; oops

# after
Content-Type: application/json
Defensive patterns

Strategy: try-catch

Validate before calling

// Preflight: confirm the mirror returns a parseable Content-Type.
ct := resp.Header.Get("Content-Type")
if _, _, err := mime.ParseMediaType(ct); err != nil {
    return fmt.Errorf("bad Content-Type %q: %w", ct, err)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "invalid Content-Type") {
    // raw error from get(); surface mirror misconfiguration, not retryable
}

Prevention

When it happens

Trigger: Mirror responds 200 with a Content-Type header that fails mime.ParseMediaType — e.g. unquoted parameters, stray characters, or an otherwise malformed media-type string. Browsers tolerate it; Go's MIME parser does not.

Common situations: Custom mirror server sets Content-Type by string concatenation without quoting parameter values; legacy server sending non-standard media type syntax.

Related errors


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