Golang imap.DialTLS configuration example

Previously, I could connect to the 143

mail server port like this:

c, err := imap.Dial(mailServer)


The above code connects to port 143 mailServer

. Now my new mail server only accepts the port 993

. Looking at the Golang source code imap

, the function DialTLS

will connect to the port 993

. The signature DialTLS

looks like this:

func DialTLS(addr string, config *tls.Config) (c *Client, err error)


Now I don't know how to build *tls.Config

. I googled but didn't find anything useful. Can anyone show me an example how to build *tls.Config


I tried to pass nil

as the second parameter, it compiles and I didn't get any runtime error. But it looks like there were no new letters, even I think there should be.

My post code looks like this:

// testimap
package main

import (

type Mail struct {
    Subject string
    Body    string
    From    string
    Uid     uint32

func FetchMail(lastUid uint32) []*Mail {
    defer func() {
        if err := recover(); err != nil {
    // Note: most of error handling code is omitted for brevity
    var (
        c   *imap.Client
        cmd *imap.Command
        rsp *imap.Response

    // Connect to the server
    c, err := imap.DialTLS(mailServer, nil)
    if err != nil {

    // Remember to log out and close the connection when finished
    defer c.Logout(30 * time.Second)

    // Print server greeting (first response in the unilateral server data queue)
    //fmt.Println("Server says hello:", c.Data[0].Info)
    c.Data = nil

    // Enable encryption, if supported by the server
    if c.Caps["STARTTLS"] {

    // Authenticate
    if c.State() == imap.Login {
        c.Login(mailSupportUser, mailSupportPw)

    //// List all top-level mailboxes, wait for the command to finish
    cmd, err = imap.Wait(c.List("", "%"))
    if err != nil {
    // Print mailbox information
    //fmt.Println("\nTop-level mailboxes:")
    //for _, rsp = range cmd.Data {
    //  fmt.Println("|--", rsp.MailboxInfo())

    // Check for new unilateral server data responses
    //for _, rsp = range c.Data {
    //  fmt.Println("Server data:", rsp)
    c.Data = nil

    // Open a mailbox (synchronous command - no need for imap.Wait)
    c.Select("INBOX", true)
    //fmt.Print("\nMailbox status:\n", c.Mailbox)

    // Fetch the headers of the 10 most recent messages
    set, err := imap.NewSeqSet(fmt.Sprint(lastUid, ":*"))
    if err != nil {
    //if c.Mailbox.Messages >= 10 {
    //  set.AddRange(c.Mailbox.Messages-9, c.Mailbox.Messages)
    //} else {
    //  set.Add("1:*")
    cmd, err = c.UIDFetch(set, "RFC822.HEADER", "RFC822.TEXT")
    if err != nil {

    // Process responses while the command is running
    //fmt.Println("\nMost recent messages:")
    mails := make([]*Mail, 0, 10)
    for cmd.InProgress() {
        // Wait for the next response (no timeout)

        // Process command data
        for _, rsp = range cmd.Data {
            if err != nil {
            header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
            uid := imap.AsNumber((rsp.MessageInfo().Attrs["UID"]))
            body := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"])
            if msg, err := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
                if err != nil {
                mail := &Mail{
                    Subject: msg.Header.Get("Subject"),
                    From:    msg.Header.Get("FROM"),
                    Body:    string(body),
                    Uid:     uid,
                if mail.Uid < lastUid {
                mails = append(mails, mail)
        cmd.Data = nil
        c.Data = nil

    // Check command completion status
    if rsp, err := cmd.Result(imap.OK); err != nil {
        if err == imap.ErrAborted {
            fmt.Println("Fetch command aborted")
        } else {
            fmt.Println("Fetch error:", rsp.Info)
    return mails



source to share

1 answer

First of all, you should use the GitHub repo project , as the Google Code project stated that development is moving on GitHub due to the closure of Google Code.This is a few commits ahead of the Google Code repository, so you won't receive any updates unless you go to the GitHub repository.

Second, looking at the package demo , passing nil

in DialTLS

as the TLS client seems to be the appropriate way to connect with the default TLS client.

From the information you provided, it seems like it might be a problem when your server is accepting connections on that port. I would see if the port is open to the client you are trying to connect to, or if your IMAP server even accepts TLS connections.

If you are absolutely sure that this is not a server issue after further debugging, I would put the issue in the GitHub tracker project to get help from people who are more familiar with the package, seeing that it is a third party package.



All Articles