hashicorp/terraform · error

file exceeds maximum part count

Error message

file exceeds maximum part count

What it means

Raised in SplitSizeToOffsetsAndLimits when the computed part count exceeds MaxCount (10000). This is the root cause error that 317 and 312 ultimately wrap. At the default DefaultFilePartSize of 128MiB, it triggers for payloads larger than 10000 * 128MiB (~1.28 TiB), making a multipart upload impossible under the configured part size.

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 c9def3e214)

Solutions

  1. Reduce the state file size below the threshold (split states, prune, externalize blobs).
  2. Raise DefaultFilePartSize to reduce totalParts (must remain within OCI's max part size and keep under MaxCount).
  3. If DefaultFilePartSize was customized, restore it to 128MiB or higher so a given size yields fewer parts.
  4. Investigate why the state grew so large; normal Terraform states are orders of magnitude smaller.

Example fix

// before: a lowered part size inflates part count over MaxCount
var DefaultFilePartSize int64 = 10 * 1024 * 1024 // 10MiB -> 10000 parts at only ~98GiB
// after: restore default so MaxCount covers ~1.28TiB
var DefaultFilePartSize int64 = 128 * 1024 * 1024
Defensive patterns

Strategy: validation

Validate before calling

// Guard the splitter explicitly:
totalParts := (size + partSize - 1) / partSize
if totalParts > MaxCount {
    return nil, 0, fmt.Errorf("file exceeds maximum part count")
}

Try / catch

if totalParts > MaxCount {
    return nil, 0, fmt.Errorf("file exceeds maximum part count")
}

Prevention

When it happens

Trigger: SplitSizeToOffsetsAndLimits computes totalParts = (size + partSize - 1) / partSize (multipart_upload.go:196) and totalParts > MaxCount (10000). Concretely size > 10000 * DefaultFilePartSize.

Common situations: A terraform.tfstate exceeding ~1.28 TiB due to runaway resources, embedded blobs, or synthetic test data; DefaultFilePartSize lowered by mistake, shrinking the per-part size and inflating part count.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/6a78ce9a78f9892a. Report an issue: GitHub.