pulumi/pulumi · error

reading decrypted log: %w

Error message

reading decrypted log: %w

What it means

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.

Source

Thrown at pkg/cmd/pulumi/logs/share.go:179

		stackName, cmdStack.LoadOnly, opts, "",
	)
	if err != nil {
		return fmt.Errorf("loading stack %q: %w", stackName, err)
	}

	sm, err := secretsManagerFromStack(ctx, s)
	if err != nil {
		return fmt.Errorf("getting secrets manager for stack %q: %w", stackName, err)
	}

	// Decrypt the entire log body.
	reader, err := encryptedlog.NewReader(ctx, f, sm.Decrypter())
	if err != nil {
		return fmt.Errorf("decrypting log: %w", err)
	}
	plaintext, err := io.ReadAll(reader)
	if err != nil {
		return fmt.Errorf("reading decrypted log: %w", err)
	}

	var processed bytes.Buffer
	if err := formatLogRecords(bytes.NewReader(plaintext), &processed, redact); err != nil {
		return fmt.Errorf("processing log: %w", err)
	}

	return writeEncryptedLog(outPath, sessionID, sessionKey, processed.Bytes())
}

// shareGzip decompresses a gzip log file, optionally redacts secrets,
// and encrypts the content with the service-provided session key.
func shareGzip(
	f *os.File, outPath string, sessionID string, sessionKey []byte, redact bool,
) error {
	gz, err := gzip.NewReader(f)
	if err != nil {
		return fmt.Errorf("log file is neither encrypted nor gzip-compressed: %w", err)

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Re-create the PLOG file with `pulumi logs` and copy it in binary-safe mode (scp, binary attachment)
  2. Verify the file size/integrity against the original (checksum comparison)
  3. If persistent, re-run the operation that produced the log and capture a new one

Example fix

// before
cat debug.plog | mail support   // text-mode mangling
// after
scp debug.plog support@host:    // binary-safe transfer
// or verify: sha256sum debug.plog on both sides
Defensive patterns

Strategy: try-catch

Validate before calling

// verify size/integrity before sharing
orig, _ := os.Stat(plogPath)
fmt.Println("size:", orig.Size()) // compare against source copy's checksum

Try / catch

plaintext, err := io.ReadAll(reader)
if err != nil {
    return fmt.Errorf("decrypted log unreadable (truncated or corrupt PLOG?): %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/e12c1e4dd60e04e6. Report an issue: GitHub.