semaphoreui/semaphore · error
unsupported TLS version
Error message
unsupported TLS version %s
What it means
parseTlsVersion maps a TLS version string (e.g. "1.2", "1.3") to the corresponding crypto/tls constant used when dialing the SMTP server. When the configured version string matches neither known case, the function returns 0 plus this error, and sendTls aborts the mail send. It is a configuration-validation guard ensuring the mailer never attempts a handshake with an invalid tls.Version value.
Solutions
- Change the configured TLS version to exactly "1.2" or "1.3" (case-sensitive).
- If the SMTP server only supports TLS 1.0/1.1, upgrade the server or remove the explicit version setting rather than forcing an unsupported value.
- Trim/normalize the value at the config-loading layer (e.g. strings.TrimSpace, lowercase) before passing it to parseTlsVersion.
- Verify the environment variable or YAML key actually feeding the value is populated and has no quotes or stray characters.
Example fix
// before (config) smtp_tls_version: "TLSv1.2" // after smtp_tls_version: "1.2"
Defensive patterns
Strategy: validation
Validate before calling
const allowed = new Set(['1.2', '1.3']);
if (!allowed.has(cfg.smtp_tls_version)) {
throw new Error(`smtp_tls_version must be "1.2" or "1.3", got: ${cfg.smtp_tls_version}`);
} Type guard
function isValidTlsVersion(v) {
return v === '1.2' || v === '1.3';
} Prevention
- Keep TLS version strings in a validated enum/constant list at config load time.
- Test mailer config parsing in CI with every supported and one unsupported value.
- Document the accepted values next to the config key so operators don't guess formats.
- Normalize input (trim, strip 'TLS '/'v' prefixes) before mapping to tls constants.
When it happens
Trigger: Setting the mailer's TLS version config to any string other than exactly "1.2" or "1.3" (case-sensitive, no "TLS " prefix, no "v") so parseTlsVersion falls through the switch and returns the error from util/mailer/mailer.go:48.
Common situations: Config files with values like "tls1.2", "TLSv1.2", "1.1", "1.0", or a version written with wrong casing/whitespace; older configs predating TLS 1.3 support; environment variable interpolation yielding an empty or unexpected string.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- unencrypted connection
- wrong host name
- OIDC sign-in failed: invalid redirect URL.
- secret does not belong to this environment
- You can't use both HTTP redirect address and port at the…
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/2062d1b1f3023d74.
Report an issue: GitHub.
Appendix: source
Thrown at util/mailer/mailer.go:48
"\r", "",
"\n", "",
"%0a", "",
"%0d", "",
)
func parseTlsVersion(version string) (uint16, error) {
switch version {
case "1.0":
return tls.VersionTLS10, nil
case "1.1":
return tls.VersionTLS11, nil
case "1.2":
return tls.VersionTLS12, nil
case "1.3":
return tls.VersionTLS13, nil
}
return 0, fmt.Errorf("unsupported TLS version %s", version)
}
// Send simply sends the defined mail via SMTP.
func Send(
secure bool,
useTls bool,
host string,
port string,
username,
password,
from,
to,
subject string,
content string,
) error {
body := bytes.NewBufferString("")
tpl, err := template.New("").Parse(mailerBase)
if err != nil {View on GitHub (pinned to 1774ccb71a)