hyperledger/fabric · error
missing block ID
Error message
missing block ID
What it means
This error is returned by extractBlockID when the mux path variable holding the block identifier (blockIDKey) is missing from the request, so serveFetchBlock cannot determine which block to fetch. The handler responds with HTTP 500 and a JSON error. It exists because the fetch-block endpoint requires a block specifier such as a number, 'latest', or 'config' in the URL.
Source
Thrown at orderer/common/channelparticipation/restapi.go:536
channelID, ok := mux.Vars(req)[channelIDKey]
if !ok {
err := errors.New("missing channel ID")
h.sendResponseJsonError(resp, http.StatusInternalServerError, err)
return "", err
}
if err := configtx.ValidateChannelID(channelID); err != nil {
err = errors.WithMessage(err, "invalid channel ID")
h.sendResponseJsonError(resp, http.StatusBadRequest, err)
return "", err
}
return channelID, nil
}
func (h *HTTPHandler) extractBlockID(req *http.Request, resp http.ResponseWriter) (string, error) {
blockID, ok := mux.Vars(req)[blockIDKey]
if !ok {
err := errors.New("missing block ID")
h.sendResponseJsonError(resp, http.StatusInternalServerError, err)
return "", err
}
if err := ValidateFetchBlockID(blockID); err != nil {
err = errors.WithMessage(err, "invalid block ID")
h.sendResponseJsonError(resp, http.StatusBadRequest, err)
return "", err
}
return blockID, nil
}
func (h *HTTPHandler) sendJoinError(err error, resp http.ResponseWriter) {
h.logger.Debugf("Failed to JoinChannel: %s", err)
switch err {
case types.ErrSystemChannelExists:
// The client is trying to join an app-channel, but the system channel exists: only GET is allowed on app channels.
h.sendResponseNotAllowed(resp, errors.WithMessage(err, "cannot join"), http.MethodGet)View on GitHub (pinned to 2736b63f8f)
Solutions
- Add the block specifier to the path, e.g. /participation/channels/mychannel/blocks/latest or /blocks/0 or /blocks/config
- Confirm the URL template used by the client fully interpolates the block ID
- Check that no middleware or proxy truncates the request path
- If validation of the value is the real issue, ensure it passes ValidateFetchBlockID (valid number, 'latest', or 'config')
Example fix
// before GET /participation/channels/mychannel/blocks // after GET /participation/channels/mychannel/blocks/latest
Defensive patterns
Strategy: validation
Validate before calling
if (!/^\d+$|^latest$|^config$/.test(blockID)) throw new Error(`invalid block ID: ${blockID}`); Type guard
function isBlockID(v: unknown): v is string | number {
return typeof v === 'number' || (typeof v === 'string' && /^\d+$|^latest$|^config$/.test(v));
} Try / catch
try {
const res = await fetch(`${base}/participation/channels/${cid}/blocks/${blockID}`);
const body = await res.json();
if (!res.ok) throw new Error(body.error ?? `HTTP ${res.status}`);
} catch (e) {
if (String(e).includes('missing block ID')) console.error('Append a block specifier: <n>, latest, or config');
else throw e;
} Prevention
- Interpolate the block specifier into the fetch-block URL template
- Only use 'number', 'latest', or 'config' as block IDs (ValidateFetchBlockID)
- Log the full request URL on failure to spot truncated paths
When it happens
Trigger: GET requests to the channel participation fetch-block endpoint whose URL does not contain the block ID path segment, so mux.Vars(req)[blockIDKey] is not present.
Common situations: Client code calling /participation/channels/{channelID}/blocks without the trailing block specifier; templated URL not interpolated; proxy truncating the path before the block ID.
Related errors
- missing channel ID
- unsupported Content-Type: %s
- invalid request method: %s
- response Content-Type is application/json only
- reading http response body: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/4d186fff60113311.
Report an issue: GitHub.