hyperledger/fabric · warning

cannot parse Mime media type

Error message

cannot parse Mime media type

What it means

serveJoin parses the request's Content-Type header with mime.ParseMediaType to confirm it is multipart/form-data and extract the boundary. If the header is missing, malformed, or not parseable, the request is rejected with 400 and this wrapped error.

Source

Thrown at orderer/common/channelparticipation/restapi.go:360

	}

	resp.Header().Set("Cache-Control", "no-store")
	resp.Header().Set("Content-Type", "application/octet-stream")
	h.sendResponseBlock(resp, blockBytes)
}

// Join a channel.
// Expect multipart/form-data.
func (h *HTTPHandler) serveJoin(resp http.ResponseWriter, req *http.Request) {
	_, err := negotiateContentType(req) // Only application/json responses for now
	if err != nil {
		h.sendResponseJsonError(resp, http.StatusNotAcceptable, err)
		return
	}

	_, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
	if err != nil {
		h.sendResponseJsonError(resp, http.StatusBadRequest, errors.Wrap(err, "cannot parse Mime media type"))
		return
	}

	block := h.multipartFormDataBodyToBlock(params, req, resp)
	if block == nil {
		return
	}

	channelID, err := ValidateJoinBlock(block)
	if err != nil {
		h.sendResponseJsonError(resp, http.StatusBadRequest, errors.WithMessage(err, "invalid join block"))
		return
	}

	info, err := h.registrar.JoinChannel(channelID, block)
	if err != nil {
		h.sendJoinError(err, resp)
		return

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Use multipart/form-data with an explicit boundary: Content-Type: multipart/form-data; boundary=<boundary>
  2. Send the request with curl -F or an HTTP client multipart API so Content-Type and boundary are set automatically
  3. Verify no proxy/middleware strips or rewrites the Content-Type header
  4. Check the wrapped inner error to identify the exact header syntax problem

Example fix

// before
curl -X POST --data-binary @config.block http://orderer/participation/v2/channels
// after
curl -X POST -F 'config-block=@config.block' http://orderer/participation/v2/channels
Defensive patterns

Strategy: validation

Validate before calling

ct := req.Header.Get("Content-Type")
mt, params, err := mime.ParseMediaType(ct)
if err != nil || mt != "multipart/form-data" || params["boundary"] == "" {
	return errors.New("use multipart/form-data with a boundary, e.g. curl -F")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "cannot parse Mime media type") {
	// fix client: send multipart/form-data; boundary=... and retry
}

Prevention

When it happens

Trigger: POST to the participation join endpoint with a Content-Type that isn't parseable multipart/form-data (missing header, typo like 'multipart/form-data' without boundary=, or wrong type such as application/octet-stream).

Common situations: Hand-rolled curl calls omitting -F (which sets multipart) and instead using --data-binary; HTTP clients setting Content-Type manually without the boundary parameter; proxies stripping or rewriting the Content-Type header.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/2cf9a857c5324a76. Report an issue: GitHub.