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

  1. Switch the handler to ctx.ReadMultipartRelated() for multipart/related requests.
  2. Branch on ctx.GetContentType() before calling ReadBody.
  3. Parse with mime/multipart yourself if you need custom semantics.
  4. 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

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


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/fd841b452df8ced3. Report an issue: GitHub.