{"record":{"id":"e12c1e4dd60e04e6","repo":"pulumi/pulumi","slug":"reading-decrypted-log-w","errorCode":null,"errorMessage":"reading decrypted log: %w","messagePattern":"reading decrypted log: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/pulumi/logs/share.go","lineNumber":179,"sourceCode":"\t\tstackName, cmdStack.LoadOnly, opts, \"\",\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"loading stack %q: %w\", stackName, err)\n\t}\n\n\tsm, err := secretsManagerFromStack(ctx, s)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"getting secrets manager for stack %q: %w\", stackName, err)\n\t}\n\n\t// Decrypt the entire log body.\n\treader, err := encryptedlog.NewReader(ctx, f, sm.Decrypter())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"decrypting log: %w\", err)\n\t}\n\tplaintext, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reading decrypted log: %w\", err)\n\t}\n\n\tvar processed bytes.Buffer\n\tif err := formatLogRecords(bytes.NewReader(plaintext), &processed, redact); err != nil {\n\t\treturn fmt.Errorf(\"processing log: %w\", err)\n\t}\n\n\treturn writeEncryptedLog(outPath, sessionID, sessionKey, processed.Bytes())\n}\n\n// shareGzip decompresses a gzip log file, optionally redacts secrets,\n// and encrypts the content with the service-provided session key.\nfunc shareGzip(\n\tf *os.File, outPath string, sessionID string, sessionKey []byte, redact bool,\n) error {\n\tgz, err := gzip.NewReader(f)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"log file is neither encrypted nor gzip-compressed: %w\", err)","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/cmd/pulumi/logs/share.go#L161-L197","documentation":"The encrypted log reader was created but reading the decrypted stream failed partway. This wraps I/O errors from io.ReadAll on the decrypting reader — corrupt ciphertext, truncation, or an underlying read error on the file.","triggerScenarios":"A PLOG file that decrypted its header but whose body is truncated or corrupted (partial upload/download, disk error), or auth-tag verification failure on tampered ciphertext.","commonSituations":"Sharing a log copied before `pulumi logs` finished writing it; transferring the file in a mode that mangled binary content (text-mode FTP, bad base64 round-trip); failing disk.","solutions":["Re-create the PLOG file with `pulumi logs` and copy it in binary-safe mode (scp, binary attachment)","Verify the file size/integrity against the original (checksum comparison)","If persistent, re-run the operation that produced the log and capture a new one"],"exampleFix":"// before\ncat debug.plog | mail support   // text-mode mangling\n// after\nscp debug.plog support@host:    // binary-safe transfer\n// or verify: sha256sum debug.plog on both sides","handlingStrategy":"try-catch","validationCode":"// verify size/integrity before sharing\norig, _ := os.Stat(plogPath)\nfmt.Println(\"size:\", orig.Size()) // compare against source copy's checksum","typeGuard":null,"tryCatchPattern":"plaintext, err := io.ReadAll(reader)\nif err != nil {\n    return fmt.Errorf(\"decrypted log unreadable (truncated or corrupt PLOG?): %w\", err)\n}","preventionTips":["Copy PLOG files only after `pulumi logs` has exited","Use binary-safe transfer (scp, git-lfs, binary attachments)","Compare checksums between the generated and shared copy"],"tags":["io","corruption","encryption"],"backgroundTag":"file-truncated-or-corrupt","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}