{"record":{"id":"b170a0eaf64a7a9f","repo":"pulumi/pulumi","slug":"encryptedlog-invalid-magic-bytes","errorCode":null,"errorMessage":"encryptedlog: invalid magic bytes","messagePattern":"encryptedlog: invalid magic bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/engine/encryptedlog/reader.go","lineNumber":48,"sourceCode":"\n// Reader reads and decrypts PLOG encrypted log files,\n// returning the original plaintext log data. It tolerates missing\n// end sentinels for crash resilience — all completed chunks are readable.\ntype Reader struct {\n\tcd *chunkDecrypter\n}\n\n// NewReader creates an Reader that decrypts log data from r.\n// The session key stored in the file header is decrypted with dec.\nfunc NewReader(\n\tctx context.Context, r io.Reader, dec config.Decrypter,\n) (*Reader, error) {\n\tvar magic [4]byte\n\tif _, err := io.ReadFull(r, magic[:]); err != nil {\n\t\treturn nil, fmt.Errorf(\"encryptedlog: reading magic: %w\", err)\n\t}\n\tif string(magic[:]) != Magic {\n\t\treturn nil, errors.New(\"encryptedlog: invalid magic bytes\")\n\t}\n\n\tvar versionBuf [1]byte\n\tif _, err := io.ReadFull(r, versionBuf[:]); err != nil {\n\t\treturn nil, fmt.Errorf(\"encryptedlog: reading version: %w\", err)\n\t}\n\tversion := versionBuf[0]\n\tif version != Version {\n\t\treturn nil, fmt.Errorf(\"encryptedlog: unsupported version %d\", version)\n\t}\n\n\tvar keyLenBuf [2]byte\n\tif _, err := io.ReadFull(r, keyLenBuf[:]); err != nil {\n\t\treturn nil, fmt.Errorf(\"encryptedlog: reading key length: %w\", err)\n\t}\n\tkeyLen := binary.BigEndian.Uint16(keyLenBuf[:])\n\n\tencryptedKeyBytes := make([]byte, keyLen)","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/engine/encryptedlog/reader.go#L30-L66","documentation":"After successfully reading the first 4 bytes, NewReader compares them against the encryptedlog Magic constant. Mismatched magic means the stream is not a Pulumi encrypted log at all — most commonly a plaintext log or a different binary format — so parsing is rejected immediately.","triggerScenarios":"Calling encryptedlog.NewReader on a log that was never encrypted (plain `pulumi up` output), a log encrypted with a different/older format, or a file whose first bytes were altered/prepended.","commonSituations":"Pointing the encrypted-log reader at ordinary log files; backend misconfig where encryption was disabled after logs were assumed encrypted; concatenating plaintext and encrypted logs.","solutions":["Confirm the log is actually encrypted (check `pulumi logs`/backend settings or the file's first bytes against the Magic constant).","If the log is plaintext, read it directly instead of through encryptedlog.NewReader.","If the format/version differs, regenerate or re-export the log from the backend that produced it rather than hand-editing bytes."],"exampleFix":"// before\nr, err := encryptedlog.NewReader(ctx, plaintextFile, dec) // invalid magic bytes\n// after\nbuf := make([]byte, 4)\nio.ReadFull(plaintextFile, buf)\nif string(buf) != encryptedlog.Magic {\n    return errors.New(\"not an encrypted log; read as plain text\")\n}\nplaintextFile.Seek(0, io.Start)\nr, err := encryptedlog.NewReader(ctx, plaintextFile, dec)","handlingStrategy":"validation","validationCode":"// Go: sniff magic bytes before decoding\nbr := bufio.NewReader(r)\nmagic, err := br.Peek(len(encryptedlog.Magic))\nif err != nil || string(magic) != encryptedlog.Magic {\n    return errors.New(\"stream is not an encrypted Pulumi log\")\n}","typeGuard":"// Go\nfunc isEncryptedLog(r io.Reader) (bool, io.Reader) {\n    br := bufio.NewReader(r)\n    magic, err := br.Peek(4)\n    return err == nil && string(magic) == encryptedlog.Magic, br\n}","tryCatchPattern":"// Go\nif _, err := encryptedlog.NewReader(ctx, br, dec); err != nil {\n    if strings.Contains(err.Error(), \"invalid magic bytes\") {\n        return errors.New(\"not an encrypted log; treat as plain text\")\n    }\n    return err\n}","preventionTips":["Only feed logs produced with encryption enabled into encryptedlog.NewReader","Detect format by peeking magic bytes before choosing a reader path","Avoid hand-editing or concatenating encrypted log files"],"tags":["encrypted-logs","format-validation","magic-bytes"],"backgroundTag":"invalid-file-format","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}