{"record":{"id":"45e2b2386cfa0799","repo":"hashicorp/terraform","slug":"expected-to-receive-state-in-d-bytes-actually-re","errorCode":null,"errorMessage":"expected to receive state in %d bytes, actually received %d bytes","messagePattern":"expected to receive state in (.+?) bytes, actually received (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/grpcwrap/provider6.go","lineNumber":1102,"sourceCode":"\t\t\t\tstateId = chunk.Meta.StateId\n\t\t\t} else {\n\t\t\t\tpanic(\"expected Meta to be set on first chunk sent to WriteStateBytes\")\n\t\t\t}\n\t\t}\n\n\t\tn, err := state.Write(chunk.Bytes)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error writing state: %w\", err)\n\t\t}\n\t\ttotalReceivedBytes += n\n\t}\n\n\tif grpcErr != nil {\n\t\treturn grpcErr\n\t}\n\n\tif int64(totalReceivedBytes) != expectedTotalLength {\n\t\treturn fmt.Errorf(\"expected to receive state in %d bytes, actually received %d bytes\", expectedTotalLength, totalReceivedBytes)\n\t}\n\n\tif totalReceivedBytes == 0 {\n\t\t// Even an empty state file has content; no bytes is not valid\n\t\treturn errors.New(\"No state data received from Terraform: No state data was received from Terraform. This is a bug and should be reported.\")\n\t}\n\n\tresp := p.provider.WriteStateBytes(providers.WriteStateBytesRequest{\n\t\tStateId:  stateId,\n\t\tTypeName: typeName,\n\t\tBytes:    state.Bytes(),\n\t})\n\n\terr := srv.SendAndClose(&proto6.WriteStateBytes_Response{\n\t\tDiagnostics: convert.AppendProtoDiag([]*proto6.Diagnostic{}, resp.Diagnostics),\n\t})\n\n\treturn err","sourceCodeStart":1084,"sourceCodeEnd":1120,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/grpcwrap/provider6.go#L1084-L1120","documentation":"Returned by the tfplugin6 WriteStateBytes handler when, after the receive loop ends cleanly (io.EOF), the total bytes received does not equal the TotalLength the client declared in its first chunk. The stream was truncated or the declared length was wrong, so the assembled state cannot be trusted.","triggerScenarios":"int64(totalReceivedBytes) != expectedTotalLength after the loop exits without a receive error.","commonSituations":"Client closed the stream before sending all chunks; client reported an incorrect TotalLength; a mid-stream send error on the client side became EOF on the server side; proxy/gateway truncation.","solutions":["Retry the state write from scratch.","Verify the client computes and advertises TotalLength correctly (sender bug).","Check logs for an interrupted or cancelled stream on the client side.","Ensure no proxy/load-balancer truncates long-lived gRPC streams."],"exampleFix":"// sender must declare the true total and send exactly that many bytes\nchunk.TotalLength = int64(len(fullStateBytes)) // must equal sum of all chunk.Bytes\n// on mismatch the server rejects:\n// \"expected to receive state in %d bytes, actually received %d bytes\"","handlingStrategy":"try-catch","validationCode":"// Sender-side: compute TotalLength exactly and send exactly that many bytes.\nvar total int64\nfor _, c := range chunks {\n    total += int64(len(c.Bytes))\n}\nchunks[0].TotalLength = total // must equal the sum received by the server","typeGuard":null,"tryCatchPattern":"// Length mismatch means the stream cannot be trusted; retry once.\nerr := client.WriteStateBytes(ctx, chunks)\nif err != nil && strings.Contains(err.Error(), \"expected to receive state in\") {\n    // recompute TotalLength, resend from scratch\n    return resend(fullState)\n}","preventionTips":["Compute TotalLength as the exact sum of all chunk byte lengths.","Do not resume a partial stream; resend the full state on mismatch.","Ensure no proxy truncates the gRPC stream."],"tags":["terraform","grpc","streaming","state","truncation","data-integrity"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}