kataras/iris · error
context: read body: cannot bind multipart/related: use ReadM
Error message
context: read body: cannot bind multipart/related: use ReadMultipartRelated instead
What it means
Returned by Context.ReadBody (content-type based auto-binding) when the request's Content-Type is multipart/related. This format has no generic struct binding: it must be decoded with the dedicated ReadMultipartRelated API, so the library refuses to bind and tells you which method to use instead. It is a deliberate routing error, not data corruption.
Source
Thrown at context/context.go:3304
// otherwise use the ReadForm,
// it's actually the same except
// ReadQuery will not fire errors on:
// 1. unknown or empty url query parameters
// 2. empty query or form (if FireEmptyFormError is enabled).
return ctx.ReadForm(ptr)
}
switch ctx.GetContentTypeRequested() {
case ContentXMLHeaderValue, ContentXMLUnreadableHeaderValue:
return ctx.ReadXML(ptr)
// "%v reflect.Indirect(reflect.ValueOf(ptr)).Interface())
case ContentYAMLHeaderValue, ContentYAMLTextHeaderValue:
return ctx.ReadYAML(ptr)
case ContentFormHeaderValue, ContentFormMultipartHeaderValue:
return ctx.ReadForm(ptr)
case ContentMultipartRelatedHeaderValue:
return fmt.Errorf("context: read body: cannot bind multipart/related: use ReadMultipartRelated instead")
case ContentJSONHeaderValue:
return ctx.ReadJSON(ptr)
case ContentProtobufHeaderValue:
msg, ok := ptr.(proto.Message)
if !ok {
return ErrContentNotSupported
}
return ctx.ReadProtobuf(msg)
case ContentMsgPackHeaderValue, ContentMsgPack2HeaderValue:
return ctx.ReadMsgPack(ptr)
default:
if ctx.Request().URL.RawQuery != "" {
// try read from query.
return ctx.ReadQuery(ptr)
}
// otherwise default to JSON.View on GitHub (pinned to 7bedaf55a0)
Solutions
- Switch the handler to ctx.ReadMultipartRelated() for multipart/related requests.
- Branch on ctx.GetContentType() before calling ReadBody.
- Parse with mime/multipart yourself if you need custom semantics.
- Send a 415 Unsupported Media Type if the endpoint does not intend to accept multipart/related.
Example fix
// before
var req Payload
if err := ctx.ReadBody(&req); err != nil { return err }
// after
switch ctx.GetContentType() {
case context.ContentMultipartRelatedHeaderValue:
mr, err := ctx.ReadMultipartRelated()
if err != nil { return err }
// handle parts
default:
var req Payload
return ctx.ReadBody(&req)
} Defensive patterns
Strategy: type-guard
Validate before calling
if strings.HasPrefix(ctx.GetContentType(), "multipart/related") {
mr, err := ctx.ReadMultipartRelated()
_ = mr // handle parts
_ = err
return
} Type guard
func isMultipartRelatedRequest(ctx *context.Context) bool {
return strings.HasPrefix(ctx.GetContentType(), context.ContentMultipartRelatedHeaderValue)
} Try / catch
var req Payload
if err := ctx.ReadBody(&req); err != nil {
if strings.Contains(err.Error(), "multipart/related") {
return ctx.ReadMultipartRelated() // route to dedicated API
}
return err
} Prevention
- Dispatch on Content-Type before any generic ReadBody call
- Never use ReadBody as a universal binder for all media types
- Return 415 with the accepted content types when rejecting multipart/related
When it happens
Trigger: Calling ctx.ReadBody(ptr) on a request whose Content-Type is multipart/related (e.g. MTOM/XOP SOAP payloads).
Common situations: SOAP MTOM endpoints consumed through a generic JSON/YAML/form read helper; middleware that blindly calls ReadBody on every request; migrating generic handlers to accept file-bearing payloads.
Related errors
- multipart related: body copy because of iris.Configuration.D
- multipart related: next part: %w
- multipart related: next part: read: %w
- ErrEmptyFormField
- dest directory: %s: eval symlinks: %w
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/fd841b452df8ced3.
Report an issue: GitHub.