Input not an X.509 certificate
The message "keytool error: java.lang.Exception: Input not an X.509 certificate" means the file passed to `keytool -importcert` did not parse as a certificate. keytool accepts a single X.509 certificate in PEM or DER form, or a PKCS#7 reply, and nothing else — so a private key, a certificate signing request, a PKCS#12 bundle, or an HTML error page saved with a `.crt` extension all produce this error. Run `openssl x509 -in file.crt -noout -subject` first: if OpenSSL also refuses the file it is not a certificate, and the extension was misleading. A PKCS#12 file needs `keytool -importkeystore` rather than `-importcert`, and a PEM whose armour lines are missing, preceded by a byte order mark, or wrapped in CRLF line endings must be re-emitted through `openssl x509` before keytool will read it.
What the error actually means #
keytool -importcert accepts exactly two things: a single X.509 certificate, in PEM or DER, or a
PKCS#7 reply from a CA. Anything else is rejected with this message, and the message never says what
the file actually was.
So the fastest route is not to fight keytool but to identify the file. The extension is not
evidence — .crt, .cer and .pem are used interchangeably for at least six different structures.
Step 1 — find out what you have #
openssl x509 -in certificate.crt -noout -subject If that succeeds, the file is a certificate and the problem is encoding — skip to armour and encoding. If it fails, read the first line to find out what you are holding:
head -1 certificate.crt Expected output
-----BEGIN CERTIFICATE-----
For a binary file, which has no readable first line:
file certificate.der Step 2 — match the label to the fix #
| First line | What the file is | What to do |
|---|---|---|
-----BEGIN CERTIFICATE----- |
A certificate | Encoding problem |
-----BEGIN CERTIFICATE REQUEST----- |
A CSR | You have the request, not the answer. Ask the CA for the issued certificate |
-----BEGIN PRIVATE KEY----- |
A private key | Keys cannot be imported with -importcert. Bundle key and certificate into a PKCS#12 first |
-----BEGIN RSA PRIVATE KEY----- |
A PKCS#1 key | Same as above |
-----BEGIN PKCS7----- |
A PKCS#7 chain | keytool usually accepts this; if not, expand it to PEM |
Binary, file says “data” |
DER, or a PKCS#12 | Convert or use -importkeystore |
<!DOCTYPE html or <html |
An HTML page | The download failed and you saved a login or error page |
A PKCS#12, PFX or P12 file #
This is a keystore, not a certificate: it holds a private key together with its chain. It needs the keystore importer, which is a different subcommand entirely:
keytool -importkeystore \
-srckeystore certificate.pfx -srcstoretype PKCS12 \
-destkeystore keystore.jks -deststoretype JKS The full walkthrough, including what happens to aliases and passwords, is on convert PFX to JKS.
A PKCS#7 or P7B file #
keytool normally reads PKCS#7 replies, but a P7B produced by Windows is sometimes DER-encoded where keytool expects PEM. Expand it into individual certificates and import them one at a time:
openssl pkcs7 -print_certs -in bundle.p7b -out expanded.pem grep -c "BEGIN CERTIFICATE" expanded.pem Then split and import each with its own alias — see convert P7B to PEM for the splitting step.
The file is a certificate, but keytool still refuses it #
OpenSSL parses the file and keytool does not. The difference is always the armour, because keytool is strict where OpenSSL is forgiving. The three usual culprits:
- A UTF-8 byte order mark before the first
-----, invisible in every editor - CRLF line endings from a Windows machine or a text-mode FTP transfer
- Extra text outside the BEGIN and END markers, such as the human-readable subject block some tools print above the certificate
Re-emitting through OpenSSL normalises all three at once, because it parses the certificate and writes a fresh, canonical PEM:
openssl x509 -in certificate.crt -out clean.crt If the file is DER rather than PEM, say so on the way in:
openssl x509 -inform der -in certificate.der -out clean-from-der.crt Then import the normalised file:
keytool -importcert -trustcacerts -noprompt \
-alias example-root \
-file clean.crt \
-keystore truststore.jks -storepass changeit Frequently asked questions
- I am importing a .pfx file and keytool refuses it. Why?
-importcertimports a certificate; a PKCS#12 file is a keystore containing a private key and its chain. Usekeytool -importkeystore -srckeystore file.pfx -srcstoretype PKCS12 -destkeystore keystore.jksinstead.- The file opens fine in a text editor and starts with BEGIN CERTIFICATE. What else could be wrong?
- A UTF-8 byte order mark before the first dash is invisible in most editors and makes keytool reject the file. So does a truncated final line. Re-emitting the file with
openssl x509 -in file.crt -out clean.crtnormalises both. - Can keytool import a chain of several certificates from one PEM file?
- It handles a PKCS#7 reply containing a chain, but a plain concatenation of PEM blocks is best split and imported one certificate at a time with distinct aliases. That also makes the truststore readable later, when you need to know which anchor came from where.
- Why does the same file work with OpenSSL but not keytool?
- OpenSSL is tolerant of text outside the BEGIN and END markers and of unusual line endings; keytool is not. When OpenSSL accepts a file that keytool rejects, encoding is the difference, and round-tripping it through
openssl x509resolves it.
References
- keytool(1), JDK 21 — what -importcert accepts, and the -importkeystore alternative
- RFC 7468: textual encodings of PKIX structures — the PEM armour rules keytool enforces strictly