A library for reading PST files (written in Go/Golang).

View on GitHub


A library for reading PST files (written in Go/Golang).

pkg.go.dev reference


go-pst is a library for reading PST files (written in Go/Golang).

The PFF (Personal Folder File) and OFF (Offline Folder File) format is used to store Microsoft Outlook e-mails, appointments and contacts. The PST (Personal Storage Table), OST (Offline Storage Table) and PAB (Personal Address Book) file format consist of the PFF format.


$ go install github.com/mooijtech/go-pst/v5
package main

import (

  pst "github.com/mooijtech/go-pst/v5/pkg"

func main() {
  startTime := time.Now()


  pstFile, err := pst.NewFromFile("../data/enron.pst")

  if err != nil {
    panic(fmt.Sprintf("Failed to open PST file: %+v\n", err))

  defer func() {
    if errClosing := pstFile.Close(); errClosing != nil {
      panic(fmt.Sprintf("Failed to close PST file: %+v\n", err))

  // Walk through folders.
  if err := pstFile.WalkFolders(func(folder pst.Folder) error {
    fmt.Printf("Walking folder: %s\n", folder.Name)

    messageIterator, err := folder.GetMessageIterator()

    if errors.Is(err, pst.ErrMessagesNotFound) {
      // Folder has no messages.
      return nil
    } else if err != nil {
      return err

    // Iterate through messages.
    for messageIterator.Next() {
      message := messageIterator.Value()

      fmt.Printf("Message subject: %s\n", message.GetSubject())

      attachmentIterator, err := message.GetAttachmentIterator()

      if errors.Is(err, pst.ErrAttachmentsNotFound) {
        // This message has no attachments.
      } else if err != nil {
        return err

      // Iterate through attachments.
      for attachmentIterator.Next() {
        attachment := attachmentIterator.Value()

        fmt.Printf("Attachment: %s\n", attachment.GetAttachFilename())

        attachmentOutput, err := os.Create(fmt.Sprintf("attachments/%s", attachment.GetAttachFilename()))

        if err != nil {
          return err
        } else if _, err := attachment.WriteTo(attachmentOutput); err != nil {
          return err

        if err := attachmentOutput.Close(); err != nil {
          return err

      if attachmentIterator.Err() != nil {
        return attachmentIterator.Err()

    return messageIterator.Err()
  }); err != nil {
    panic(fmt.Sprintf("Failed to walk folders: %+v\n", err))

  fmt.Printf("Time: %s\n", time.Since(startTime).String())


go-pst is open-source under the GNU Affero General Public License Version 3 - AGPLv3. Fundamentally, this means that you are free to use go-pst for your project, as long as you don’t modify go-pst. If you do, you have to make the modifications public.


Feel free to contact me if you have any questions.
Name: Marten Mooij
Email: info@mooijtech.com




This library is tested on the following datasets: