{"record":{"id":"ea4bde6c1db4e012","repo":"hashicorp/terraform","slug":"error-reading-error-message-s","errorCode":null,"errorMessage":"Error reading error message: %s","messagePattern":"Error reading error message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/communicator/ssh/communicator.go","lineNumber":638,"sourceCode":"\t}\n\n\treturn nil\n}\n\n// checkSCPStatus checks that a prior command sent to SCP completed\n// successfully. If it did not complete successfully, an error will\n// be returned.\nfunc checkSCPStatus(r *bufio.Reader) error {\n\tcode, err := r.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif code != 0 {\n\t\t// Treat any non-zero (really 1 and 2) as fatal errors\n\t\tmessage, _, err := r.ReadLine()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Error reading error message: %s\", err)\n\t\t}\n\n\t\treturn errors.New(string(message))\n\t}\n\n\treturn nil\n}\n\nvar testUploadSizeHook func(size int64)\n\nfunc scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, size int64) error {\n\tif testUploadSizeHook != nil {\n\t\ttestUploadSizeHook(size)\n\t}\n\n\tif size == 0 {\n\t\t// Create a temporary file where we can copy the contents of the src\n\t\t// so that we can determine the length, since SCP is length-prefixed.","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/communicator/ssh/communicator.go#L620-L656","documentation":"Raised in checkSCPStatus when the SCP protocol returns a non-zero status byte (indicating a remote error) and the subsequent attempt to read the human-readable error message line from the SCP response stream fails. The communicator already detected an SCP-level error but could not extract the textual detail, so only the transport-level read error is surfaced.","triggerScenarios":"During an SCP file or directory upload, the remote scp process sends a non-zero status code. The communicator calls r.ReadLine() to read the associated message, but the bufio reader hits an I/O error (connection reset, EOF, or timeout) before a newline is received.","commonSituations":"The remote scp process crashed or the SSH connection was severed mid-transfer (TCP reset, server kill, disk full on remote). The remote scp binary terminated abnormally before completing the error response.","solutions":["Inspect the underlying transport error wrapped by %s; if it indicates a broken pipe or EOF, the remote scp process died mid-transfer.","Check remote disk space and scp availability (scp must be installed and on PATH).","Retry the upload; transient network failures during large file transfers are common.","Increase the connection timeout and verify network stability to the remote host."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Check for SCP error message read failures and surface transport detail\nif err := comm.Upload(dst, reader); err != nil {\n    if strings.Contains(err.Error(), \"Error reading error message\") {\n        // The remote scp process likely died mid-transfer\n        log.Printf(\"[ERROR] SCP transfer failed with transport error: %v\", err)\n        return fmt.Errorf(\"scp transfer interrupted (remote scp may have crashed): %w\", err)\n    }\n    return err\n}","preventionTips":["Ensure the remote host has scp installed and on PATH.","Monitor remote disk space to prevent scp crashes mid-transfer.","Use retry logic for large file uploads that may hit transient network issues."],"tags":["scp","upload","io-reader","network","terraform"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}