# 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.

Source: https://certguru.io/errors/keytool-not-an-x509-certificate/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

> **The exact message**
>
> ```
>   keytool error: java.lang.Exception: Input not an X.509 certificate
>   ```
>   It appears in response to `keytool -importcert`, and occasionally as
>   `Input not an X.509 certificate` with no exception prefix on older JDKs.

## 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

*Does OpenSSL see a certificate?*

```bash
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](#the-file-is-a-certificate-but-keytool-still-refuses-it). If it fails, read
the first line to find out what you are holding:

*What does the armour say?*

```bash
head -1 certificate.crt
```

Expected output:

```
-----BEGIN CERTIFICATE-----
```

For a binary file, which has no readable first line:

*Identify a binary file*

```bash
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](#the-file-is-a-certificate-but-keytool-still-refuses-it) |
| `-----BEGIN CERTIFICATE REQUEST-----` | A [CSR](/formats/csr/) | You have the request, not the answer. Ask the CA for the issued certificate |
| `-----BEGIN PRIVATE KEY-----` | A [private key](/formats/key/) | Keys cannot be imported with `-importcert`. Bundle key and certificate into a PKCS#12 first |
| `-----BEGIN RSA PRIVATE KEY-----` | A [PKCS#1 key](/formats/key/) | Same as above |
| `-----BEGIN PKCS7-----` | A [PKCS#7 chain](/formats/pkcs7-p7b/) | keytool usually accepts this; if not, [expand it to PEM](#a-pkcs7-or-p7b-file) |
| Binary, `file` says "data" | DER, or a [PKCS#12](/formats/pkcs12-pfx-p12/) | [Convert or use -importkeystore](#a-pkcs12-pfx-or-p12-file) |
| ` **The HTML case is more common than it sounds**
>
> Fetching a certificate from a CA portal or an internal wiki with `curl` or `wget` while
>   unauthenticated saves the login page under the filename you asked for. It is several kilobytes,
>   has the right name, and is not a certificate. `head -1` catches it in one second.

## 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:

*Import a PKCS#12 as a keystore*

```bash
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](/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:

*Expand a P7B into PEM certificates*

```bash
openssl pkcs7 -print_certs -in bundle.p7b -out expanded.pem
```

*Confirm what came out*

```bash
grep -c "BEGIN CERTIFICATE" expanded.pem
```

Then split and import each with its own alias — see [convert P7B to PEM](/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:

*Normalise the encoding*

```bash
openssl x509 -in certificate.crt -out clean.crt
```

If the file is DER rather than PEM, say so on the way in:

*DER in, PEM out*

```bash
openssl x509 -inform der -in certificate.der -out clean-from-der.crt
```

Then import the normalised file:

*Import the cleaned certificate*

```bash
keytool -importcert -trustcacerts -noprompt \
  -alias example-root \
  -file clean.crt \
  -keystore truststore.jks -storepass changeit
```

> **Give every anchor a meaningful alias**
>
> `-alias mycert` on four different imports leaves a truststore nobody can audit later. Name the
>   alias after the CA, so that `keytool -list` reads as an inventory of what you have decided to
>   trust.


## Frequently asked questions

### I am importing a .pfx file and keytool refuses it. Why?

`-importcert` imports a certificate; a PKCS#12 file is a keystore containing a private key and its chain. Use `keytool -importkeystore -srckeystore file.pfx -srcstoretype PKCS12 -destkeystore keystore.jks` instead.

### 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.crt` normalises 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 x509` resolves it.


## References

- [keytool(1), JDK 21](https://docs.oracle.com/en/java/javase/21/docs/specs/man/keytool.html) — what -importcert accepts, and the -importkeystore alternative
- [RFC 7468: textual encodings of PKIX structures](https://www.rfc-editor.org/rfc/rfc7468) — the PEM armour rules keytool enforces strictly

## Related pages

- https://certguru.io/errors/pkix-path-building-failed/
- https://certguru.io/errors/pem-routines-no-start-line/
- https://certguru.io/formats/pkcs7-p7b/
- https://certguru.io/formats/pkcs12-pfx-p12/
- https://certguru.io/convert/p7b-to-pem/
- https://certguru.io/convert/pfx-to-jks/
- https://certguru.io/formats/pem/

--
CertGuru — https://certguru.io
