Why an SSL certificate won't import into CompleteFTP, and how to fix it
Almost every certificate that fails to import into CompleteFTP fails for one of a small number of reasons, and the message you get is the same regardless of which one it is, a dialog titled Could not load certificate, saying:
Failed to load server certificate from <path>. Please ensure a private key has been supplied and that the correct password has been used
That single message covers a wrong password, a key that doesn't belong to the certificate, a key in a format CompleteFTP won't parse, a file whose extension selects the wrong parser, and a Windows key-store permission problem. This article separates them and gives the command-line route for Linux.
It covers the server certificate used for FTPS and HTTPS. SSH/SFTP host keys and user public keys are a different mechanism and are not covered here, an SSL certificate has no effect on SFTP.
The short version
- The private key file's extension decides how it is parsed. In CompleteFTP Manager the private
key file must be named
.pvk(Microsoft PVK) or.pem(OpenSSL PEM). A.keyor.pfxfile selected at the key prompt is rejected, rename a PEM-format key to.pem. - A private key generated by CompleteFTP's CSR wizard is PEM, not PVK, and is not encrypted, from
25.1.0 onward. It is written in PEM format with a
.pemextension, and the password the wizard asked for is discarded, so when prompted for it at import time an empty password works, whatever you typed. On 25.0.6 and earlier the wizard wrote an encrypted PVK and the password is real; open the file to tell which you have, PEM begins-----BEGIN. - Know which password you are being asked for. For a
.pfx/.p12it is the password on the PKCS#12 file, and it is always required. For a separate private key file it is the key's own password, which is used only if that key is actually encrypted, if it is not, any value including blank is accepted. Either way, a rejected password is usually not a password problem. See "When it doesn't work" below. - Only RSA keys work. An EC/ECDSA certificate cannot be used as a CompleteFTP server certificate.
- Click APPLY CHANGES. The import dialog writes the certificate into the pending configuration; nothing reaches the server until you apply.
On Linux, or to script it, there is no dialog, use the CLI:
completeftp site cert import "Default Site" /path/to/certificate.crt "" /path/to/private.key ""
The CLI takes the certificate, its password, the private key file and the key's password, and applies
the change itself. Pass "" for a password that doesn't exist.
What CompleteFTP actually accepts
There are two file slots: a certificate file, and, only if the certificate file does not already contain the private key, a private key file.
| Slot | CompleteFTP Manager | CLI / JSS |
|---|---|---|
| Certificate file | .cer, .crt, .pem, .pfx, .p12 in the file dialog. .p7b also works but the dialog's filter hides it, so you have to type the file name. |
Any name; the extension chooses the parser. pfx/p12 → PKCS#12, p7b → PKCS#7, anything else → PEM or DER. |
| Private key file | .pvk or .pem only. Any other extension raises Unknown private key format: <path>. |
Any name, but the content must be PEM. A PVK file cannot be used on this route. |
Inside those containers:
| Format | Accepted | Notes |
|---|---|---|
PKCS#12 / PFX (.pfx, .p12) |
Yes | Certificate and key in one file. The key must be exportable. |
PKCS#7 (.p7b) |
Yes | Certificates only, no private key, so you will be prompted for one. |
PEM certificate (-----BEGIN CERTIFICATE-----) |
Yes | Multiple certificates in one file are read; but only in CompleteFTP Manager. See "Intermediate and root certificates". |
DER / binary certificate (.cer, .crt) |
Yes | Detected by the absence of BEGIN CERTIFICATE in the file. |
PEM key, PKCS#1 (-----BEGIN RSA PRIVATE KEY-----) |
Yes | Encrypted (Proc-Type: 4,ENCRYPTED) or plain. |
PEM key, PKCS#8 (-----BEGIN PRIVATE KEY-----) |
Yes | Plain. |
PEM key, PKCS#8 encrypted (-----BEGIN ENCRYPTED PRIVATE KEY-----) |
Yes | Including PBES2/PBKDF2 with AES-CBC, which is what OpenSSL 3.x produces by default. |
PVK (.pvk) |
Manager only | Microsoft's format: RC4-encrypted with an SHA-1-derived key. |
OpenSSH key (-----BEGIN OPENSSH PRIVATE KEY-----) |
No | Convert first: ssh-keygen -p -m PEM -f key. |
| EC / ECDSA key, any container | No | See "Only RSA keys work" below. |
| DSA key | No | Parsed, then rejected because it is not RSA. |
DEK algorithms accepted in a traditional encrypted PEM key are AES-128/192/256, DES, DES-EDE, DES-EDE3, Blowfish and RC2, in CBC, CFB, ECB or OFB mode.
Where the certificate lives, and what uses it
- There is one certificate per site, held in CompleteFTP's own configuration database
(
config.db), not in the Windows certificate store. - FTPS and HTTPS on a site share that one certificate. In CompleteFTP Manager the field appears twice, as Server certificate (also used in HTTPS) under Advanced FTP/FTPS Settings, and as Server certificate under Advanced HTTP/HTTPS Settings, but both edit the same value. Setting it in one place sets it in the other.
- The Admin site has its own certificate. The admin interface (port 14983 for SFTP, and its own HTTPS port) is a separate site, so a certificate installed on your data site does not apply to it. In Enterprise MFT, turn on Show system users/folders/sites in the Options menu to see the Admin site under Sites. In Standard and Professional, use the Admin panel → Show advanced administrator connection settings.
- Multiple sites require Enterprise MFT. In the other editions there is one data site and therefore one server certificate for it.
- The server reloads the certificate automatically when the stored bytes change. A service restart is not required, but existing connections keep using the old one.
The procedure
CompleteFTP Manager
- Settings (or Sites in Enterprise MFT) → FTP/FTPS → Advanced FTP/FTPS Settings → Security Settings → Server certificate, then the ... button.
- Click Import a certificate from a file. Answer Yes to The existing certificate will be overwritten.
- Choose the certificate file. If you choose a name whose extension isn't recognised you get
Please select a file with one of the following extensions: cer, pem, pfx, p12. - For a PFX or P12 you are asked for the file's password (Please enter the password of the PFX/P12 File). For a PEM file that also contains an encrypted private key you are asked for the key's password instead.
- If the certificate file has no private key in it, you are asked to Choose a private key file,
.pvkor.pem, and then for its password. - The dialog now shows the certificate's details. Click OK.
- Click APPLY CHANGES in the main window. This step is the one most often missed: until you click it the certificate has not reached the server.
Two things to expect while this runs. The file is parsed on the UI thread, so CompleteFTP Manager can show Not Responding for several seconds, that is normal, wait rather than killing it. And the identity fields shown at step 6 are read from whichever certificate the manager picks as the leaf, which is not always the one you expect when the file contains a chain (see below).
CLI (the only interface on Linux)
# what is installed now
completeftp site cert export "Default Site"
# certificate and key in one PFX
completeftp site cert import "Default Site" /etc/ssl/cert.pfx "pfxpassword"
# certificate and key as separate files
completeftp site cert import "Default Site" /etc/ssl/cert.crt "" /etc/ssl/cert.key "keypassword"
# self-signed, for testing only
completeftp site cert generate "Default Site" ftp.example.com "Example Ltd" IT London ENG GB \
2026-01-01 2029-01-01 2048
site cert import applies the change itself, there is no separate apply step. site list gives
you the site names, including the Admin site, which is listed last.
The CLI is enabled out of the box on Linux. Run it as root or as the completeftp account, which
are the accounts that can reach the server. On Windows the admin CLI is off by default and has to
be enabled with --enable-admin-cli on the service's binary path.
Three differences from the manager worth knowing:
- The CLI does not care what the private key file is called, as long as its contents are PEM.
- The CLI cannot read a PVK file at all. Convert it first:
openssl rsa -inform pvk -in key.pvk -out key.pem. -
Pass the certificate and the private key as separate files, or use a PFX. A single PEM file containing both the certificate and the key is not handled on this route: the certificate is read but the key inside it is ignored, and the import fails with
Certificate file doesn't include private key, so this must be supplied separatelyThis is a defect in the CLI/JSS import path, not something you have done wrong.
When it doesn't work
Ordered by how often each comes up in support tickets.
1. The private key is fine. The file extension isn't
In CompleteFTP Manager the private key parser is chosen from the file's extension, not its contents:
.pvk is read as a Microsoft PVK blob, .pem as PEM, and anything else is refused outright with
System.IO.IOException: Unknown private key format: C:\certs\wildcard.pfx
The key file dialog offers All Files as well as PVK or PEM Files, which makes it easy to select a
.key, .pfx or extensionless file and get that error. Copy the file to a name ending in .pem and
try again.
The reverse mistake is worse, because it reports a password problem. A PEM-format key named .pvk is
handed to the PVK reader, which fails to recognise the header and throws
System.Security.Cryptography.CryptographicException: Invalid data and/or password
That message is raised both for a wrong password and for a file that is not a PVK at all. If you are
certain of the password, suspect the format: a real PVK file begins with the bytes 1E F1 B5 B0, while
a PEM file begins with -----BEGIN.
2. The key file contains a certificate as well, with the certificate first
CompleteFTP reads exactly one PEM object from the private key file. If the file starts with a
certificate block, which is what openssl pkcs12 -in file.pfx -out all.pem produces, the first
object read is the certificate, and the import fails with
Wrong type returned from ReadObject(): Org.BouncyCastle.X509.X509Certificate
(the class name varies between builds). Split the file so that the key file contains only the
-----BEGIN ... PRIVATE KEY----- block, or use -nocerts:
openssl pkcs12 -in file.pfx -nocerts -out key.pem
Leading Bag Attributes / subject= / issuer= lines before the BEGIN marker are harmless and do
not need to be removed.
3. The password is rejected but OpenSSL says it is correct
Work through these in order.
- Is the key actually encrypted? If it is not, the password box is decorative: any value, including blank, is accepted. A key generated by CompleteFTP's own CSR wizard is not encrypted on 25.1.0 and later, despite the wizard asking you to set and confirm a password. So "the password I set when I generated the CSR doesn't work" and "a blank password works" are both expected on those releases. On 25.0.6 and earlier the wizard produced an encrypted PVK, so there the password does matter and a rejection means something else, most often the file-extension trap above.
-
Does the key match the certificate? Compare the public keys; identical hashes mean they are a pair.
openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 openssl pkey -in private.key -pubout -outform DER | openssl dgst -sha256If they differ, no password will help, you need the key that was generated with the CSR this certificate was issued against, or a re-key. Older releases said so plainly:
Error: The public key of the certificate does not match the value specified. - Is it a PKCS#12 password or a private key password? For a
.pfxthe prompt wants the password on the PKCS#12 file. For a separate key file it wants the password on the key. They are frequently different, and people enter the wrong one. - On the CLI, a genuinely wrong key password is reported precisely:
Could not decrypt key. Please check the password.If you get the generic manager message instead, the cause is one of the others in this list.
If you no longer have the private key at all, there is nothing to import. A certificate cannot be installed without its key, in CompleteFTP or in any other server. If the CSR was generated by CompleteFTP, the key was written to the file you chose at that time and exists nowhere else. Your only route is to re-key the certificate with the CA.
4. Keyset does not exist and friends. Windows key-store permissions
System.Security.Cryptography.CryptographicException: Keyset does not exist
System.Security.Cryptography.CryptographicException: Access denied
Key not valid for use in specified state
Importing a certificate on Windows makes CompleteFTP Manager write a key container through the Windows crypto API, and the account it needs is the account running CompleteFTP Manager, not the service account. This is why the same file imports on one machine and not another, and why the manager's log shows it touching a path under the interactive user's profile:
C:\Users\<username>\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-...
In order of likelihood:
- The user running the manager has no write access to
%APPDATA%\Microsoft\Crypto\RSA. Run the manager as a user who does, or as Administrator. (Running as Administrator is a diagnostic, not a fix, if it works, fix the permissions.) - A stale key container from an earlier import is in the way. PEM key imports all reuse a single
fixed container name, so a container left behind by a different user or a failed attempt collides
with the new one. Move the contents of
%APPDATA%\Microsoft\Crypto\RSAto a backup directory and retry, or retry under a different Windows account. Create a new self-signed certificate has the same weakness, every generation uses one fixed container name, which is why that can fail withKey not valid for use in specified stateon a machine where an ordinary import also fails. -
The private key in the PFX is marked non-exportable. OpenSSL will not warn you about this; Windows will:
certutil -dump yourfile.pfxIf the Private Key entry says Not exportable, re-export the PFX with an exportable key, or split it into a separate PEM certificate and PEM key:
openssl pkcs12 -in file.pfx -clcerts -nokeys -out certificate.pem openssl pkcs12 -in file.pfx -nocerts -nodes -out key.pem
Separately, the service account needs read/write access to
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, because that is where the server side loads the
stored certificate's key. That is the right advice for a server that can't use an already-imported
certificate, and the wrong advice for an import that fails in the manager. None of this applies on
Linux, where no Windows key store is involved.
5. It imported, but the server can't load it
Look in the server log, not the manager log. The chain of symptoms is:
ERROR SecureConfiguration Failed to load server certificate: Access is denied.
ERROR SecureConfiguration Server certificate does not have a private key!
and then, on an HTTPS or implicit-FTPS port,
ERROR SocketListener OnConnected failed: The certificate cannot be set to a null reference when creating a server socket.
which the browser reports as a connection reset (ERR_CONNECTION_RESET, PR_CONNECT_RESET_ERROR) with
plain HTTP still working. On an explicit-FTPS port the same condition gives the client a bare
431 Server error and logs
ERROR AuthCommand User attempted AUTH but no certificate available
On Windows the account running the service needs read/write access to
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, because that is the machine key store the server
loads the certificate's key from. If the log says
Failed to load server certificate: Access is denied., see "If you are on an older release" below
before changing permissions, that exact message was a regression in one release.
You may also see, at import time,
An internal error occurred when the certificate was being saved to the configuration (private key lost).
That check runs only on the separate-key-file path and means the key was associated in memory but did
not survive being written to the configuration, the same key-store permission problem, caught earlier.
Failed to load certificate with private key in the manager log is the earlier stage of the same
failure: the key file parsed, but Windows would not attach the resulting key to the certificate.
A related pair comes from the socket layer rather than the configuration layer. Alongside
The certificate cannot be set to a null reference when creating a server socket. you may see
If a certificate is specified, it must have a private key., that one means the certificate loaded but
its key did not, which almost always means the key is not RSA (section 6).
6. Only RSA keys work
A certificate whose key is EC/ECDSA cannot be used as a CompleteFTP server certificate in any current release. In CompleteFTP Manager the import fails after the password prompt with
The certificate key algorithm is not supported.
(that text comes from .NET, when the manager reads the key size for display). On the CLI and JSS route the message is CompleteFTP's own:
Only certificates with RSA keys are currently supported.
The server side agrees: the TLS layer refuses ECDSA credentials and logs
ECDHE_ECDSA certificates not supported. Those suites are not in the server's offered list, so a
client that supports only ECDSA fails to negotiate cleanly rather than breaking mid-handshake. Use an RSA certificate. DSA and Ed25519 keys are likewise not usable here.
Ed25519 is supported for SSH host keys, which is a different setting.
7. After OK the dialog shows the CA's details instead of yours
When the file contains more than one certificate, the manager picks the "leaf" heuristically: the one that has a private key, failing that the one whose Basic Constraints say it is not a CA, and failing that simply the first certificate in the file. With some chains that lands on the intermediate or root, so the Server name/address and Organization fields change to the CA's after you click OK.
This is a display problem, not a failed import. Don't judge the result from the dialog, check what the server actually presents:
openssl s_client -connect ftp.example.com:990 -showcerts
openssl s_client -connect ftp.example.com:443 -showcerts
The same dialog shows (Error) in red, or [Not set], when the stored certificate cannot be read at
all.
8. The manager can't be used at all
On Linux there is no manager, so if you are looking for the import dialog on a Linux installation,
it does not exist. Use completeftp site cert import. The Linux code path
is also the simpler one, no Windows key store, so sections 4 and 5 do not apply.
Intermediate and root certificates
CompleteFTP will read a certificate file containing your certificate plus the CA's intermediates, concatenate them, yours first, and it will store them. But the chain CompleteFTP presents to clients at handshake time is rebuilt on the server machine from the leaf certificate, using the operating system's certificate stores. It is not taken from the file you imported.
The practical consequence: if clients report an incomplete or untrusted chain, install the CA's intermediate certificate into the server machine's Intermediate Certification Authorities (Local Computer) store. With a public CA this usually happens by itself, because Windows fetches and caches intermediates. With an internal PKI it will not. The chain build also performs an online revocation check, so a server with no outbound access to the CA's CRL/OCSP endpoints may produce a partial chain.
Do not put a root or intermediate certificate in the certificate slot on its own. It will import, because CompleteFTP does not validate imported certificates, and the site will then present the wrong certificate.
For client certificate verification (Clients must supply certificates → Require valid certificate, not available in the Standard Edition), CompleteFTP has no trust store of its own: the client's issuer must be in the Windows Trusted Root Certification Authorities store. That is what this message means:
The certificate could not be verified: UntrustedRoot - A certification chain processed correctly but terminated in a root certificate not trusted by the trust provider.
Two current defects worth knowing about
- The CSR wizard's private key password is collected and discarded on 25.1.0 and later. The key file written alongside the CSR is an unencrypted PEM key. Treat that file as a secret in its own right, and expect a blank password to be accepted when you import. 26.1.0 added a confirmation field to that prompt, which makes the wizard look more careful about a password it still throws away.
.pvk-named PEM keys left over from an older install are the single most common cause of "the password is definitely correct" reports. Renaming to.pemfixes them; the CSR wizard stopped producing PVK at 25.1.0.
If you are on an older release
All of these are fixed. If you are on an affected release, upgrading is the fix, there is no configuration workaround for any of them.
| Symptom | Affected | Fixed in |
|---|---|---|
Index was out of range. Must be non-negative and less than the size of the collection. importing most PFX files |
24.1.0 | 25.0.0 |
Failed to load server certificate: Access is denied. when the service runs as anything other than SYSTEM |
26.0.0 | 26.0.1 |
Unable to cast object of type 'AsymmetricCipherKeyPair' to type 'RsaPrivateCrtKeyParameters' on some PEM keys |
before 13.1.0 | 13.1.0 |
Failed to find certificate's private key. Error: -2146885621, a bare Windows error number instead of a reason; it meant a key-store permission problem |
25.0.x and earlier | 25.1.0 |
After the import succeeds
- Click APPLY CHANGES.
- Reconnect a client. Existing sessions keep the old certificate; there is no need to restart the service, but there is a need to make a new connection.
- Verify what is being served, per port, with
openssl s_client -connect <host>:<port> -showcerts. Run it against every HTTPS and FTPS port you have, including the Admin site's, a certificate installed on one site does not appear on another. - If clients now report untrusted or unknown certificate rather than a failed import, the
certificate is installed and the remaining problem is trust: a self-signed certificate (the default,
CN
localhost) is in no client's trust store, and a CA-issued certificate whose CN/SAN does not match the hostname the client dialled will be rejected too.NET::ERR_CERT_COMMON_NAME_INVALIDwhen browsinghttps://localhostis this, not an import failure. - Export includes the private key only for
.pfxand.p12. Export the current certificate to a file writes the key alongside the certificate when the filename ends in.pfxor.p12, and never when it ends in.ceror.pem. If you are copying a certificate to a second server, a cluster node, or a rebuilt machine, export to.pfx. Some older support advice says a self-signed certificate generated inside CompleteFTP can never be exported with its key; that is no longer the case on current releases. (completeftp site cert export <site> --exportPrivateKey truedoes the same from the CLI, emitting PEM.)
What to send support
If none of the above resolves it, the useful artefacts are the manager log and the server log, both at debug level, covering the failed import.
- Manager: in the connect dialog choose Other settings..., set the manager logging level to Full
diagnostic (slow), connect, retry the import, then collect
C:\Users\<username>\AppData\Local\EnterpriseDT\CompleteFTP\Logs\Diagnostics.log. - Server: Monitoring → Log Files → Server logging level =
Debug→ APPLY CHANGES, then collectC:\ProgramData\Enterprise Distributed Technologies\Complete FTP\Logs\Diagnostics.log(/var/log/completeftp/Diagnostics.logon Linux).
The manager log line you are looking for names the file and the underlying exception:
2026-07-30 09:44:21,636 ERROR CertForm [] Failed to load server certificate from C:\certs\wildcard.crt
System.IO.IOException: Unknown private key format: C:\certs\wildcard.pfx
Also useful: the first and last lines of your private key file (they identify the format without
disclosing the key), and openssl pkcs12 -info -in <file> output for a PFX. Note that the Save
diagnostics zip deliberately strips SSL certificates from its copy of the configuration, so it will not
tell anyone what you imported.
If you send certificate and key files, zip them with a password. A production private key should not be sent at all, re-key instead.
Related
- Product guide: How to set up the server certificate, How to import SSL certificates in other formats, How to set up a CA SSL certificate, How to buy a CA certificate, How to install a CA SSL certificate, Step-by-step: request a CA certificate, Step-by-step: install a CA certificate, How to set up client certificates (FTPS), Certificates and certificate authorities, Obtaining keys and certificates, Server and client validation, Securing FTP with TLS, Administrator site settings, CLI reference, Server log files, Manager log files.
- Note that How to import SSL certificates in other formats states that the private key generated with a CSR is in PVK format. That was true up to 25.0.6 and has been wrong since 25.1.0, where it became PEM.
- Adjacent KB article: How to enable Debug logging in CompleteFTP for troubleshooting
(
completeftp-debug-logging), the full detail on log levels, log locations on Windows and Linux, and producing a log that contains only the failure. - For background on what a certificate is and how TLS uses it, see How SSL, TLS and SSH work and What is FTPS?.
Other technical articles
- CompleteFTP service fails to start after an upgrade: how to find the cause and fix it
- CompleteFTP: System.OutOfMemoryException during SFTP, or a service that stops responding
- Does edtFTPnet/PRO support .NET 8? Which assembly to reference for .NET Framework, .NET Core and .NET 5+
- How to disable weak ciphers and encryption algorithms in CompleteFTP
- How to enable Debug logging in CompleteFTP for troubleshooting
- How to export and import CompleteFTP configuration between servers and versions
- IP filtering and whitelisting in CompleteFTP: what it supports and how to configure it
- Passive FTP and FTPS data connection failures in CompleteFTP: login works, the directory listing times out
- SFTP login fails with "No supported authentication methods available (server sent: publickey)" or "Permission denied (publickey)"
- Using Active Directory, Entra ID (Azure AD), SAML and LDAP groups to control who can log in to CompleteFTP
- Why SFTP transfers fail with "ConsumeWindowSpace timed out", and how to fix it