Javamail defaults to port 25 instead of custom port when connecting to Gmail SMTP

I’m working on a Groovy application that needs to send emails through Gmail’s SMTP service using Javamail. Even though I configure it to use port 587, the connection attempts keep defaulting to port 25.

Error message I keep seeing:

DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 25, isSSL false
Caught: javax.mail.SendFailedException: Send failure (javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 25)

My current implementation:

import javax.mail.*
import javax.mail.internet.*

class GmailAuthenticator extends Authenticator {
    public PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication('[email protected]', 'mypassword')
    }
}

def emailConfig = [
    user: "[email protected]",
    pass: "mypassword", 
    server: "smtp.gmail.com",
    portNum: "587",
    recipient: "[email protected]",
    subject: "Test Email",
    content: "Hello from Groovy"
]

def mailProps = new Properties()
mailProps.put("mail.smtp.user", emailConfig.user)
mailProps.put("mail.smtp.host", emailConfig.server)
mailProps.put("mail.smtp.port", emailConfig.portNum)
mailProps.put("mail.smtp.starttls.enable", "true")
mailProps.put("mail.smtp.debug", "true")
mailProps.put("mail.smtp.auth", "true")
mailProps.put("mail.smtp.socketFactory.port", emailConfig.portNum)
mailProps.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
mailProps.put("mail.smtp.socketFactory.fallback", "false")

def authenticator = new GmailAuthenticator()
def mailSession = Session.getInstance(mailProps, authenticator)
mailSession.setDebug(true)

def message = new MimeMessage(mailSession)
message.setText(emailConfig.content)
message.setSubject(emailConfig.subject)
message.setFrom(new InternetAddress(emailConfig.user))
message.addRecipient(Message.RecipientType.TO, new InternetAddress(emailConfig.recipient))
Transport.send(message)

I can connect to Gmail SMTP on port 587 using other email clients without issues. What configuration am I missing that would force Javamail to respect the specified port number?

yeah, classic javamail props mistake. you’re using socketFactory.class which forces ssl immediately, but port 587 needs starttls instead. comment out the socketFactory lines and only keep starttls.enable=true - that’ll fix it right away.

Had this exact issue last month while troubleshooting a similar setup. The root of the problem is that Javamail detects your socket factory configuration and attempts to use implicit SSL, which is unsupported by Gmail on port 587. When the handshake fails, Javamail silently defaults to port 25. You’ll also notice the debug output indicates useAuth false despite mail.smtp.auth being set to true; this occurs due to the SSL/TLS conflict disrupting the authentication process. Make sure to remove the socket factory properties, and remember that if you have 2FA enabled, you will need to use an app password rather than your regular Gmail password, as standard passwords won’t work for SMTP authentication regardless of port configurations.

Your SSL config is conflicting. You’re setting both STARTTLS and SSL socket factory properties at the same time, which confuses Javamail about which protocol to use. When you specify javax.net.ssl.SSLSocketFactory for port 587, you’re telling it to use implicit SSL - but Gmail doesn’t support that on 587. So it falls back to port 25 instead.

Remove these three lines:

  • mailProps.put("mail.smtp.socketFactory.port", emailConfig.portNum)
  • mailProps.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
  • mailProps.put("mail.smtp.socketFactory.fallback", "false")

Port 587 uses STARTTLS (explicit TLS), not implicit SSL. Your mail.smtp.starttls.enable property is already correct.

I hit this exact same issue last year - removing the socket factory config fixed it immediately. Gmail’s 587 port wants a plain connection that upgrades to TLS, not SSL from the start.

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.