hyperledger/fabric · warning

invalid request method: %s

Error message

invalid request method: %s

What it means

The version info HTTP handler only accepts GET requests; any other HTTP method is rejected with HTTP 400 Bad Request and this message embedded in a JSON errorResponse body. It exists to enforce the handler's contract that version information is read-only. The offending method is echoed back so the caller can see what was sent.

Source

Thrown at core/operations/version.go:27

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/hyperledger/fabric-lib-go/common/flogging"
)

type VersionInfoHandler struct {
	CommitSHA string `json:"CommitSHA,omitempty"`
	Version   string `json:"Version,omitempty"`
}

func (m *VersionInfoHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	switch req.Method {
	case http.MethodGet:
		m.sendResponse(resp, http.StatusOK, m)
	default:
		err := fmt.Errorf("invalid request method: %s", req.Method)
		m.sendResponse(resp, http.StatusBadRequest, err)
	}
}

type errorResponse struct {
	Error string `json:"Error"`
}

func (m *VersionInfoHandler) sendResponse(resp http.ResponseWriter, code int, payload any) {
	if err, ok := payload.(error); ok {
		payload = &errorResponse{Error: err.Error()}
	}
	js, err := json.Marshal(payload)
	if err != nil {
		logger := flogging.MustGetLogger("operations.runner")
		logger.Errorw("failed to encode payload", "error", err)
		resp.WriteHeader(http.StatusInternalServerError)
		return

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Issue the request with GET: curl http://<ops-host>:<ops-port>/version.
  2. Fix any monitoring/health-check configuration to use GET for this endpoint.
  3. If a preflight/intermediate proxy sends OPTIONS, exclude /version from preflight handling or accept the 400 as non-fatal.

Example fix

// before
curl -X POST http://localhost:9443/version
// after
curl http://localhost:9443/version
Defensive patterns

Strategy: try-catch

Validate before calling

if req, err := http.NewRequest(http.MethodGet, versionURL, nil); err != nil || req.Method != http.MethodGet {
    return fmt.Errorf("/version only supports GET")
}

Try / catch

resp, err := http.Get(versionURL)
if err != nil { return err }
if resp.StatusCode == http.StatusBadRequest {
    var e struct{ Error string `json:"Error"` }
    json.NewDecoder(resp.Body).Decode(&e)
    return fmt.Errorf("version endpoint rejected request (use GET): %s", e.Error)
}

Prevention

When it happens

Trigger: Sending POST, PUT, DELETE, HEAD, or OPTIONS to the peer's operations-server /version endpoint instead of GET — e.g. curl -X POST, or a monitoring tool configured with a health-check that writes.

Common situations: Automation or dashboards misconfigured to POST to /version; browsers or proxies issuing OPTIONS preflights; developers testing the endpoint with a mutation method; health-check templates that reuse a POST-based check for all endpoints.

Related errors


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