hyperledger/fabric · warning

invalid request method: %s

Error message

invalid request method: %s

What it means

serveNotAllowed is the catch-all for requests whose HTTP method is not registered for the matched route. It returns 405 (via sendResponseNotAllowed) with an 'invalid request method: %s' message, and if the route includes a block ID it advertises GET as the only allowed method. It exists to give clients a precise, machine-readable rejection when they use the wrong verb.

Source

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

	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)
}

func negotiateContentType(req *http.Request) (string, error) {
	acceptReq := req.Header.Get("Accept")
	if len(acceptReq) == 0 {
		return "application/json", nil

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Use the correct verb: POST to join, PUT to update (with channel ID in path), GET to list/fetch, DELETE to remove
  2. Read the Allow header on the 405 response — it lists the accepted methods for the route
  3. If a block ID is in the path, use GET (fetch-block only supports GET)
  4. Update scripts/tools that target the older pre-2.5 channel creation APIs

Example fix

// before
DELETE /participation/channels/mychannel/blocks/latest
// after
GET /participation/channels/mychannel/blocks/latest
Defensive patterns

Strategy: validation

Validate before calling

const allowed = { 'POST': '/participation/channels', 'PUT': `/participation/channels/${cid}`, 'GET': `/participation/channels/${cid}/blocks/${b}`, 'DELETE': `/participation/channels/${cid}` };
const expected = Object.entries(allowed).find(([, u]) => url.endsWith(u.replace(cid, cid)));
if (method !== 'GET' && url.includes('/blocks/')) throw new Error('fetch-block only supports GET');

Type guard

type ChannelMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
function isAllowedMethod(m: string, hasBlockID: boolean): m is ChannelMethod {
  return hasBlockID ? m === 'GET' : ['GET', 'POST', 'PUT', 'DELETE'].includes(m);
}

Try / catch

try {
  const res = await fetch(url, { method });
  if (res.status === 405) {
    const allow = res.headers.get('Allow');
    throw new Error(`Use one of: ${allow}`);
  }
} catch (e) {
  if (String(e).startsWith('Use one of:')) console.error('Wrong HTTP method for this route:', e.message);
  else throw e;
}

Prevention

When it happens

Trigger: Sending an unsupported method to any channelparticipation endpoint, e.g. POST to /participation/channels/{id} (only GET/DELETE allowed), DELETE on the fetch-block route, or PUT on list endpoints.

Common situations: Swapping PUT/POST for join vs update; using DELETE where the API expects GET for listing; generic API clients auto-negotiating methods; scripts copied from older Fabric versions where the method mapping differed.

Related errors


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