hyperledger/fabric · error
form contains too many parts
Error message
form contains too many parts
What it means
This error is returned by the channel participation REST API when a POST /channel join request's multipart/form-data body contains extra parts beyond exactly one config-block file part and zero value parts. The endpoint is strict: the form must have exactly one file field named 'config-block' and no additional form values, otherwise the request is rejected with HTTP 400. It exists to prevent ambiguous joins where a client sends conflicting or unexpected payload fields.
Source
Thrown at orderer/common/channelparticipation/restapi.go:442
func (h *HTTPHandler) multipartFormDataBodyToBlock(params map[string]string, req *http.Request, resp http.ResponseWriter) *cb.Block {
boundary := params["boundary"]
reader := multipart.NewReader(
http.MaxBytesReader(resp, req.Body, int64(h.config.MaxRequestBodySize)),
boundary,
)
form, err := reader.ReadForm(2 * int64(h.config.MaxRequestBodySize))
if err != nil {
h.sendResponseJsonError(resp, http.StatusBadRequest, errors.Wrap(err, "cannot read form from request body"))
return nil
}
if _, exist := form.File[FormDataConfigBlockKey]; !exist {
h.sendResponseJsonError(resp, http.StatusBadRequest, errors.Errorf("form does not contains part key: %s", FormDataConfigBlockKey))
return nil
}
if len(form.File) != 1 || len(form.Value) != 0 {
h.sendResponseJsonError(resp, http.StatusBadRequest, errors.New("form contains too many parts"))
return nil
}
fileHeader := form.File[FormDataConfigBlockKey][0]
file, err := fileHeader.Open()
if err != nil {
h.sendResponseJsonError(resp, http.StatusBadRequest, errors.Wrapf(err, "cannot open file part %s from request body", FormDataConfigBlockKey))
return nil
}
blockBytes, err := io.ReadAll(file)
if err != nil {
h.sendResponseJsonError(resp, http.StatusBadRequest, errors.Wrapf(err, "cannot read file part %s from request body", FormDataConfigBlockKey))
return nil
}
block := &cb.Block{}
err = proto.Unmarshal(blockBytes, block)View on GitHub (pinned to 2736b63f8f)
Solutions
- Remove all form fields except the single 'config-block' file part from the request
- Ensure the field is sent as a file part (multipart file), not a plain value field, and that no other value parts are present
- If using curl, keep only: curl -F 'config-block=@genesis.block' and delete other -F/--form-string options
- Inspect the client framework for automatically appended hidden fields and disable them for this request
Example fix
// before curl -X POST .../join -F 'config-block=@genesis.block' -F 'submit=1' // after curl -X POST .../join -F 'config-block=@genesis.block'
Defensive patterns
Strategy: validation
Validate before calling
// Go: validate the form before sending
w := multipart.NewWriter(&buf)
if len(extraValues) != 0 || len(extraFiles) != 0 {
return errors.New("join request must contain only one 'config-block' file part and no value parts")
}
fw, _ := w.CreateFormFile("config-block", "genesis.block")
fw.Write(blockBytes)
w.Close() Type guard
func isJoinFormValid(fileCount, valueCount int) bool {
return fileCount == 1 && valueCount == 0
} Prevention
- Send exactly one file part named 'config-block' and nothing else
- Disable auto-added hidden fields (CSRF tokens, submit buttons) for this request
- Test the request with curl -F 'config-block=@genesis.block' before wiring UI code
When it happens
Trigger: POSTing to /participation/v1/channels/{channel}/join (serveJoin) with multipart form data that has more than one file part, any additional non-file form fields (form.Value non-empty), or extra file fields alongside the 'config-block' part.
Common situations: Clients auto-adding CSRF or metadata fields to the form; submitting both a genesis block and a config-update file; curl scripts appending extra -F parameters (e.g. a stray submit=1 field); UI frameworks that append hidden inputs alongside the file input.
Related errors
- cannot open file part %s from request body
- cannot read file part %s from request body
- invalid request method: %s
- form does not contains part key: %s
- cannot unmarshal file part %s into a block
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/5c28e879caeec084.
Report an issue: GitHub.