hyperledger/fabric · warning

unsupported Content-Type: %s

Error message

unsupported Content-Type: %s

What it means

serveBadContentType fires when a request that requires a body (join or update) arrives without an accepted Content-Type header. The handler rejects it with HTTP 400 and an 'unsupported Content-Type' message listing what was sent. The API only accepts specific Content-Types for channel join/update payloads.

Source

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

		return
	}

	h.logger.Debugf("Failed to remove channel: %s, err: %s", channelID, err)

	switch err {
	case types.ErrSystemChannelExists:
		h.sendResponseNotAllowed(resp, errors.WithMessage(err, "cannot remove"), http.MethodGet)
	case types.ErrChannelNotExist:
		h.sendResponseJsonError(resp, http.StatusNotFound, errors.WithMessage(err, "cannot remove"))
	case types.ErrChannelPendingRemoval:
		h.sendResponseJsonError(resp, http.StatusConflict, errors.WithMessage(err, "cannot remove"))
	default:
		h.sendResponseJsonError(resp, http.StatusBadRequest, errors.WithMessage(err, "cannot remove"))
	}
}

func (h *HTTPHandler) serveBadContentType(resp http.ResponseWriter, req *http.Request) {
	err := errors.Errorf("unsupported Content-Type: %s", req.Header.Values("Content-Type"))
	h.sendResponseJsonError(resp, http.StatusBadRequest, err)
}

func (h *HTTPHandler) serveNotAllowed(resp http.ResponseWriter, req *http.Request) {
	err := errors.Errorf("invalid request method: %s", req.Method)

	if _, ok := mux.Vars(req)[blockIDKey]; ok {
		h.sendResponseNotAllowed(resp, err, http.MethodGet)
		return
	}

	if _, ok := mux.Vars(req)[channelIDKey]; ok {
		h.sendResponseNotAllowed(resp, err, http.MethodGet, http.MethodDelete)
		return
	}

	h.sendResponseNotAllowed(resp, err, http.MethodGet, http.MethodPost, http.MethodPut)
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set the header explicitly: Content-Type: application/json (or multipart/related when submitting a config block for join)
  2. Inspect req.Header.Values('Content-Type') reported in the message and correct it to a supported type
  3. Remove duplicate/malformed Content-Type headers that produce an unexpected value list
  4. Update the client library/SDK to one that sets the correct Content-Type for channelparticipation endpoints

Example fix

// before
curl -X POST http://orderer:7053/participation/channels -d '{...}'
// after
curl -X POST http://orderer:7053/participation/channels -H 'Content-Type: application/json' -d '{...}'
Defensive patterns

Strategy: validation

Validate before calling

const ct = headers['Content-Type'] ?? headers['content-type'];
if (!ct || !/^(application\/json|multipart\/related)/.test(Array.isArray(ct) ? ct.join(',') : ct)) {
  throw new Error(`set a supported Content-Type before calling join/update; got: ${ct}`);
}

Type guard

function isSupportedContentType(v: unknown): v is 'application/json' | 'multipart/related' {
  return typeof v === 'string' && /^(application\/json|multipart\/related)/.test(v);
}

Try / catch

try {
  const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body });
  const out = await res.json();
  if (!res.ok) throw new Error(out.error ?? `HTTP ${res.status}`);
} catch (e) {
  if (String(e).includes('unsupported Content-Type')) console.error('Resend with Content-Type: application/json');
  else throw e;
}

Prevention

When it happens

Trigger: POST /participation/channels (join) or PUT /participation/channels/{id} (update) sent with no Content-Type, or with a Content-Type other than the supported application/json (or multipart/related for join with config block), so the switch in the content-type dispatch falls to the default case.

Common situations: curl -d without -H 'Content-Type: application/json'; HTTP clients defaulting to text/plain or application/x-www-form-urlencoded; sending form data instead of a JSON join body; clients omitting the header on empty-body join requests that still require the type.

Related errors


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