kataras/iris · error

multipart related: next part: read: %w

Error message

multipart related: next part: read: %w

What it means

Same ReadMultipartRelated flow, but this error wraps a failure from io.ReadAll(part): the part boundary was found and NextPart succeeded, yet reading the part's bytes failed (connection dropped, truncated part, or read error). It distinguishes 'failed while reading part contents' from 'failed locating the next part'.

Source

Thrown at context/context.go:3089

		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)
		if err != nil {
			return MultipartRelated{}, fmt.Errorf("multipart related: next part: read: %w", err)
		}

		contentID := part.Header.Get("Content-ID")
		contentIDs = append(contentIDs, contentID)
		contents[contentID] = MultipartRelatedContent{ // replace if same Content-ID appears, which it shouldn't.
			ID:      contentID,
			Headers: http.Header(part.Header),
			Body:    b,
		}
	}

	if len(contents) != len(contentIDs) {
		contentIDs = distinctStrings(contentIDs)
	}

	result := MultipartRelated{
		ContentIDs: contentIDs,
		Contents:   contents,

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Check the wrapped error for connection-reset/timeout and ask the client to retry the upload.
  2. Raise server timeouts and body-size limits for large multipart payloads.
  3. Return 400/408 appropriately instead of 500 when the client aborted.
  4. Verify client-side that the full part body is flushed before closing the connection.

Example fix

// before
mr, err := ctx.ReadMultipartRelated()
if err != nil { return err }
// after
mr, err := ctx.ReadMultipartRelated()
if err != nil {
    if errors.Is(err, io.ErrUnexpectedEOF) {
        ctx.StatusCode(iris.StatusBadRequest)
        return errors.New("truncated multipart part")
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if ctx.Request().ContentLength > maxSize {
    return errors.New("payload too large")
}

Try / catch

mr, err := ctx.ReadMultipartRelated()
if err != nil {
    if errors.Is(err, io.ErrUnexpectedEOF) {
        ctx.StatusCode(iris.StatusBadRequest)
        return errors.New("truncated multipart part")
    }
    return err
}

Prevention

When it happens

Trigger: ctx.ReadMultipartRelated where a part's body is incomplete: client disconnect mid-part, chunked transfer interrupted, or an I/O error on the request stream.

Common situations: Timeouts on very large parts (images/embedded attachments in MTOM); mobile clients dropping connections; gateway buffering limits cutting off part bodies.

Related errors


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