hashicorp/terraform · error
file exceeds maximum part count
Error message
file exceeds maximum part count
What it means
Thrown by SplitSizeToOffsetsAndLimits() when the computed number of parts exceeds MaxCount (10000). Each part is DefaultFilePartSize (128MB), so this triggers when the input data exceeds approximately 1.28 terabytes. It is a hard guard preventing OCI multipart uploads beyond the platform's part-count limit.
Solutions
- Check whether DefaultFilePartSize was mutated by a test — if so, reset it or reduce test data size.
- Verify the state file is not corrupted or bloated with unexpected content.
- If this is a test, use data smaller than MaxCount * (test DefaultFilePartSize) — e.g. with 100-byte parts, keep data under 1MB.
- In production, if state is genuinely enormous, restructure into smaller workspace-specific states.
Example fix
// In tests, keep data within bounds of mutated part size: // At DefaultFilePartSize=100, MaxCount=10000 -> max safe size = 1,000,000 bytes // Use test data well under that limit testData := make([]byte, 999900) // safe under 10000 parts at 100 bytes each
Defensive patterns
Strategy: validation
Validate before calling
// Validate data size before calling SplitSizeToOffsetsAndLimits
func canSplitToValidParts(size int64, partSize, maxCount int64) bool {
if partSize <= 0 {
return false
}
totalParts := (size + partSize - 1) / partSize
return totalParts <= maxCount
}
// Usage before multipart upload:
if !canSplitToValidParts(dataSize, DefaultFilePartSize, MaxCount) {
return fmt.Errorf("cannot upload: size %d exceeds %d parts at %d bytes each", dataSize, MaxCount, DefaultFilePartSize)
} Prevention
- Pre-check the size-to-parts ratio before attempting multipart split.
- In tests, keep fixture data well below MaxCount * (test part size).
- Monitor state file size growth as part of CI/CD pipeline.
When it happens
Trigger: Directly computed: totalParts = (size + 128MB - 1) / 128MB. If totalParts > 10000, the error fires. Called from objectMultiPartSplit() which is invoked from multiPartUploadImpl() during state Put operations exceeding 128MB.
Common situations: Never seen with legitimate Terraform/OpenTofu state files. Can surface in unit tests that lower DefaultFilePartSize (e.g. to 100 bytes in backend_test.go) and then pass data that produces more than 10000 100-byte chunks (i.e. >1MB of test data at that setting).
Related errors
- error splitting data into parts
- auth must be one of ' ' or ' ' or ' ' or ' ' or ' ' or
- can't delete default state
- error creating multipart upload
- error reading source block
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/6a78ce9a78f9892a.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/oci/multipart_upload.go:198
}
sourceBlocks[i] = objectStorageSourceBlock{
section: io.NewSectionReader(bytes.NewReader(m.Data), start, end-start),
blockNumber: common.Int(i + 1),
}
}
return sourceBlocks, nil
}
/*
SplitSizeToOffsetsAndLimits splits a file size into chunks based on DefaultFilePartSize.
Returns the byte offsets and byte limits for each chunk.
Returns an error if the size exceeds MaxCount parts.
*/
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)View on GitHub (pinned to d32a084675)