hashicorp/terraform · warning
error reading source block
Error message
error reading source block %d: %w
What it means
Thrown by uploadPartsWorker() when reading from a section reader fails during multipart upload part preparation. The section reader is backed by bytes.NewReader over the in-memory state data, so a read failure is theoretically near-impossible — bytes.NewReader.Read never returns an error for non-nil buffers. This is defensive error handling for an edge case that should not occur under normal conditions.
Solutions
- Check for concurrent modification of the upload data buffer — ensure m.Data is not being mutated during the multipart upload.
- Verify memory integrity — this error is not expected under normal Go execution and may indicate a deeper system issue.
- Add logging to capture the exact error value and blockNumber to diagnose the unlikely root cause.
- If this recurs, the fallback in client.go:147 (single-part upload) should still succeed for sizes <= MaxFilePartSize.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate the data buffer before multipart upload
func validateUploadData(data []byte) error {
if data == nil {
return fmt.Errorf("upload data is nil")
}
if len(data) == 0 {
return fmt.Errorf("upload data is empty")
}
return nil
} Try / catch
// Wrap multipart upload with graceful error handling
if err := multipartUploadData.multiPartUploadImpl(ctx); err != nil {
if strings.Contains(err.Error(), "error reading source block") {
// Defensive error — log and fall back to single-part upload
logger.Warn("section read failed, falling back to single-part upload", "error", err)
return c.uploadSinglePartObject(ctx, data, sum[:])
}
return err
} Prevention
- Ensure the data buffer is not concurrently modified during multipart upload operations.
- Validate data is non-nil and non-empty before entering the multipart code path.
- Leverage the existing fallback to single-part upload in client.go for resilient state writes.
When it happens
Trigger: block.section.Read(buffer) returns a non-nil error. Since block.section is an io.NewSectionReader wrapping bytes.NewReader(m.Data), the only way Read returns an error is if the underlying reader is in an invalid state or buffer allocation produced a nil reader path — both effectively unreachable with well-formed data.
Common situations: This error is practically dead code in production. If encountered, it suggests memory corruption, a nil m.Data that somehow passed earlier nil-checks, or a concurrency issue where the underlying data was modified during upload.
Related errors
- can not read private key from
- can't read
- error creating multipart upload
- error splitting data into parts
- error splitting source data
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/9ad55099b6905813.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/multipart_upload.go:212
func SplitSizeToOffsetsAndLimits(size int64) ([]int64, int64, error) {
partSize := DefaultFilePartSize
totalParts := (size + partSize - 1) / partSize
if totalParts > MaxCount {
return nil, 0, fmt.Errorf("file exceeds maximum part count")
}
offsets := make([]int64, totalParts)
for i := range offsets {
offsets[i] = int64(i) * partSize
}
return offsets, partSize, nil
}
func (ctx *objectStorageMultiPartUploadContext) uploadPartsWorker() {
for block := range ctx.sourceBlocks {
buffer := make([]byte, block.section.Size())
_, err := block.section.Read(buffer)
if err != nil {
ctx.errChan <- fmt.Errorf("error reading source block %d: %w", block.blockNumber, err)
return
}
tmpLength := int64(len(buffer))
sum := md5.Sum(buffer)
uploadPartRequest := &objectstorage.UploadPartRequest{
UploadId: ctx.multipartUploadResponse.UploadId,
ObjectName: ctx.multipartUploadResponse.Object,
NamespaceName: ctx.multipartUploadResponse.Namespace,
BucketName: ctx.multipartUploadResponse.Bucket,
ContentLength: &tmpLength,
UploadPartBody: io.NopCloser(bytes.NewReader(buffer)),
UploadPartNum: block.blockNumber,
ContentMD5: common.String(base64.StdEncoding.EncodeToString(sum[:])),
RequestMetadata: common.RequestMetadata{
RetryPolicy: getDefaultRetryPolicy(),
},
}
View on GitHub (pinned to d32a084675)