kataras/iris · error

multipart related: body copy because of iris.Configuration.D

Error message

multipart related: body copy because of iris.Configuration.DisableBodyConsumptionOnUnmarshal: %w

What it means

Returned by ReadMultipartRelated when the request body is being recorded (IsRecordingBody, typically because DisableBodyConsumptionOnUnmarshal is enabled) and the internal GetBody copy step fails. The error wraps the underlying copy failure and means the body could not be buffered so the multipart reader cannot safely be constructed from a re-readable stream.

Source

Thrown at context/context.go:3069

	if err != nil {
		return MultipartRelated{}, err
	}

	if !strings.HasPrefix(contentType, ContentMultipartRelatedHeaderValue) {
		return MultipartRelated{}, ErrEmptyForm
	}

	var (
		contentIDs []string
		contents   = make(map[string]MultipartRelatedContent)
	)

	if ctx.IsRecordingBody() {
		// * remember, Request.Body has no Bytes(), we have to consume them first
		// and after re-set them to the body, this is the only solution.
		body, restoreBody, err := GetBody(ctx.request, true)
		if err != nil {
			return MultipartRelated{}, fmt.Errorf("multipart related: body copy because of iris.Configuration.DisableBodyConsumptionOnUnmarshal: %w", err)
		}
		setBody(ctx.request, body) // so the ctx.request.Body works
		defer restoreBody()        // so the next ctx.GetBody calls work.
	}

	multipartReader := multipart.NewReader(ctx.request.Body, params["boundary"])
	for {
		part, err := multipartReader.NextPart()
		if err != nil {
			if err == io.EOF {
				break
			}

			return MultipartRelated{}, fmt.Errorf("multipart related: next part: %w", err)
		}
		defer part.Close()

		b, err := io.ReadAll(part)

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Inspect the wrapped underlying error (%w) for the real cause (timeout, reset, size limit).
  2. Disable body recording for large uploads or raise the body limit configuration.
  3. Ask the client to retry if the connection reset mid-upload; verify client aborts.
  4. Test with a smaller payload to separate size-related failures from encoding problems.

Example fix

// before
mr, err := ctx.ReadMultipartRelated()
if err != nil { return err }
// after
mr, err := ctx.ReadMultipartRelated()
if err != nil {
    if strings.Contains(err.Error(), "body copy") {
        app.Logger().Warn("multipart body copy failed, likely aborted upload")
    }
    ctx.StatusCode(iris.StatusBadRequest)
    return err
}
Defensive patterns

Strategy: try-catch

Type guard

func isBodyCopyFailure(err error) bool {
    return strings.Contains(err.Error(), "body copy because of iris.Configuration")
}

Try / catch

mr, err := ctx.ReadMultipartRelated()
if err != nil {
    if strings.Contains(err.Error(), "body copy") {
        ctx.StatusCode(iris.StatusBadRequest)
        return fmt.Errorf("upload aborted or unreadable: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: ctx.ReadMultipartRelated on a request with body recording/DisableBodyConsumptionOnUnmarshal where GetBody(ctx.request, true) fails (e.g. read error, client aborted, malformed stream).

Common situations: Large multipart/related uploads hitting body-size limits or client disconnects mid-transfer; proxy interruptions; misconfigured body-size limits in servers or gateways.

Related errors


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