AlistGo/alist · critical

FTP mandatory TLS has been enabled, but the certificate fail

Error message

FTP mandatory TLS has been enabled, but the certificate failed to load: %w

What it means

server/ftp.go loads a TLS certificate from the configured FTP key/cert paths via getTlsConf. If loading fails while TLS is required (implicit TLS or mandatory encryption — i.e. tlsRequired != ClearOrEncrypted), the FTP server refuses to start with this wrapped error.

Source

Thrown at server/ftp.go:57

		transferType = ftpserver.TransferTypeBinary
	}
	activeConnCheck := ftpserver.IPMatchDisabled
	if conf.Conf.FTP.EnableActiveConnIPCheck {
		activeConnCheck = ftpserver.IPMatchRequired
	}
	pasvConnCheck := ftpserver.IPMatchDisabled
	if conf.Conf.FTP.EnablePasvConnIPCheck {
		pasvConnCheck = ftpserver.IPMatchRequired
	}
	tlsRequired := ftpserver.ClearOrEncrypted
	if setting.GetBool(conf.FTPImplicitTLS) {
		tlsRequired = ftpserver.ImplicitEncryption
	} else if setting.GetBool(conf.FTPMandatoryTLS) {
		tlsRequired = ftpserver.MandatoryEncryption
	}
	tlsConf, err := getTlsConf(setting.GetStr(conf.FTPTLSPrivateKeyPath), setting.GetStr(conf.FTPTLSPublicCertPath))
	if err != nil && tlsRequired != ftpserver.ClearOrEncrypted {
		return nil, fmt.Errorf("FTP mandatory TLS has been enabled, but the certificate failed to load: %w", err)
	}
	return &FtpMainDriver{
		settings: &ftpserver.Settings{
			ListenAddr:                conf.Conf.FTP.Listen,
			PublicHost:                lookupIP(setting.GetStr(conf.FTPPublicHost)),
			PassiveTransferPortGetter: newPortMapper(setting.GetStr(conf.FTPPasvPortMap)),
			FindPasvPortAttempts:      conf.Conf.FTP.FindPasvPortAttempts,
			ActiveTransferPortNon20:   conf.Conf.FTP.ActiveTransferPortNon20,
			IdleTimeout:               conf.Conf.FTP.IdleTimeout,
			ConnectionTimeout:         conf.Conf.FTP.ConnectionTimeout,
			DisableMLSD:               false,
			DisableMLST:               false,
			DisableMFMT:               true,
			Banner:                    setting.GetStr(conf.Announcement),
			TLSRequired:               tlsRequired,
			DisableLISTArgs:           false,
			DisableSite:               false,
			DisableActiveMode:         conf.Conf.FTP.DisableActiveMode,

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Set valid FTP TLS private key and public cert paths in settings and confirm both files exist and are readable
  2. Validate the pair: openssl x509 -in cert.pem -noout -modulus vs openssl rsa -in key.pem -noout -modulus must match
  3. Regenerate a self-signed cert if the old one is corrupt: openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
  4. Or relax the setting to ClearOrEncrypted if TLS is not actually required
Defensive patterns

Strategy: validation

Validate before calling

if tlsRequired != ftpserver.ClearOrEncrypted {
    if _, err := tls.LoadX509KeyPair(certPath, keyPath); err != nil {
        return fmt.Errorf("validate FTP cert pair before enabling TLS: %w", err)
    }
}

Prevention

When it happens

Trigger: Starting the FTP server with FTPImplicitTLS or FTPMandatoryTLS enabled while the private key/public cert paths are unset, point to missing files, contain an invalid PEM, or the key does not match the cert.

Common situations: Enabling FTP TLS in settings without first uploading/generating certificates; paths pointing to old/self-signed certs that expired into unreadable files; copy-pasting only one of the two PEM blocks.

Understand the failure class

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/e0f089874d528d9d. Report an issue: GitHub.