Need help with lettre error - network error: Resource temporarily unavailable (os error 11)

I'm still learning Rust, trying to make an email microservice using our SMTP server running on our own VPS that has been created using aaPanel, the smtp details works with nodemailer properly with this configuration:

    const transporter = createTransport({
      host: cfg.smtp.host,
      port: cfg.smtp.port,
      secure: cfg.smtp.secure,
      auth: cfg.smtp.auth,
      // In development, ignore certificate errors
      tls: {
        rejectUnauthorized: process.env.NODE_ENV === 'production'
      }
    } as any);

but getting this error below in rust:

[+] Sending email...
network error: Resource temporarily unavailable (os error 11)
network error: Resource temporarily unavailable (os error 11)
[+] Email sending processed

here's my email.rs util file:

use anyhow::Error;
use lettre::{
    Message, SmtpTransport, Transport,
    message::header::ContentType,
    transport::smtp::{
        authentication::{Credentials, Mechanism},
        client::{Tls, TlsParameters},
    },
};

use crate::types::system::Smtp;

pub struct EmailData {
    pub from: String,
    pub from_name: String,
    pub to: String,
    pub to_name: String,
    pub reply_to: String,
    pub reply_to_name: String,
    pub subject: String,
    pub body: String,
}

pub fn send(smtp_cfg: &Smtp, data: EmailData) -> Result<(), Error> {
    let email = Message::builder()
        .from(format!("{} <{}>", data.from_name, data.from).parse()?)
        .reply_to(format!("{} <{}>", data.reply_to_name, data.reply_to).parse()?)
        .to(format!("{} <{}>", data.to_name, data.to).parse()?)
        .subject(data.subject)
        .header(ContentType::TEXT_HTML)
        .body(data.body)?;

    let host = smtp_cfg.host.clone();
    let port = smtp_cfg.port.clone();
    let user = smtp_cfg.username.clone();
    let pass = smtp_cfg.password.clone();

    let tls = Tls::Required(
        TlsParameters::builder(smtp_cfg.host.clone())
            .dangerous_accept_invalid_certs(true)
            .build()?,
    );

    let sender = SmtpTransport::builder_dangerous(host.as_str())
        .port(port)
        .credentials(Credentials::new(user, pass))
        .authentication(vec![Mechanism::Login])
        .tls(tls)
        .build();

    if let Err(err) = sender.test_connection() {
        println!("{}", err);
    } else {
        println!("[+] Connected properly");
    }

    if let Err(err) = sender.send(&email) {
        println!("{}", err);
    } else {
        println!("Failed to send");
    }

    Ok(())
}

for testing, I'm calling this inside my main.rs:

use std::net::SocketAddr;

use anyhow::Error;
use axum::{Router, routing};
use tokio::{self};

use crate::types::system::AppState;

mod controllers;
mod routes;
mod services;
mod types;
mod utils;

#[tokio::main]
async fn main() -> Result<(), Error> {
    let cfg = utils::config::load(true)?;
    let state = AppState { cfg: cfg.clone() };

    println!("[+] Sending email...");

    let _ = utils::email::send(&cfg.smtp, utils::email::EmailData {
        from: "contact@test.com".to_string(),
        from_name: "Mailer Service".to_string(),
        to: "test@gmail.com".to_string(),
        to_name: "Nowshad".to_string(),
        reply_to: "contact@test.com".to_string(),
        reply_to_name: "Mailer Service".to_string(),
        subject: "Test message from Rust lettre".to_string(),
        body: "<h1>Hello World</h1>".to_string(),
    });

    println!("[+] Email sending processed");

    let app = Router::new()
        .route("/health", routing::get(async || "Hello World"))
        .with_state(state);

    let addr = SocketAddr::from(([127, 0, 0, 1], 7777));

    axum_server::bind(addr)
        .serve(app.into_make_service())
        .await
        .unwrap();

    Ok(())
}

I've tried both Mechanism::Plain and Mechanism::Login, but getting same error in both cases, chatgpt was also unable to provide any solution that works

What is in smtp_cfg? Error essentially says that whatever host-port pair you've set there is currently unreachable.

oh, really sorry for not mentioning them

host: smtp.domain.com
port: 465
username: contact@domain.com

I assume there is no server named smtp.domain.com. Do you use a real host name?
If so, check that port 465 is opened (i.e use telnet of TNC on Window)

Funny enough, that seems to be a real SMTP server, although I couldn't find any documentation - it responds to curl --http0.9 https://smtp.domain.com:465 (with an error, but this is still not a "connection refused"), and verbose logs show some SMTP-looking lines.

True:) 465 is implicit TLS, so I one might use openssl

openssl s_client -connect smtp.domain.com:465

it says

220 ESMTP Tue, 16 Sep 2025 22:59:16 -0400: UCE strictly prohibited

I wonder if topicstarter used TLS.

According to whois, domain.com was registered in 1994 by ICANN, it should be like example.org but I do not see any RFC either

no, actually I just used dummy domain name here instead of the actual one just to keep privacy, but the actual configuration works with the nodemailer in nodejs seamlessly, btw, the SSL certificate of the domain and for the subdomain smtp are created using lets-encrypt and cloudflare api, our dns server is cloudflare

this is actually a dummy domain here, actual one is different, btw, the port 465 is open as we're already using the same smtp server with the same config in nodejs by using nodemailer

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.