# acme4j: a Java client for ACME certificate issuance

> acme4j is a Java client for the Automatic Certificate Management Environment protocol as specified in RFC 8555, with support for the http-01, dns-01 and tls-alpn-01 challenges, IP identifier validation, short-term renewal and S/MIME certificates. It has been in use since December 2015, is Apache 2.0 licensed and runs on JRE 17 or later.

**shred/acme4j** — Java client for ACME (Let's Encrypt)

- Repository: https://github.com/shred/acme4j
- Website: https://acme4j.shredzone.org
- Stars: 594 · Forks: 104
- Language: Java
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/shred-acme4j

## What the ACME client actually does for you

acme4j is a Java client for the Automatic Certificate Management Environment protocol as specified in RFC 8555. ACME itself is a protocol that a certificate authority and an applicant can use to automate the process of verification and certificate issuance, and this library helps you connect to an ACME server and perform all necessary steps to manage certificates.

The scope is the whole protocol, not a subset of it. The library is fully RFC 8555 compliant, and it supports the http-01, dns-01 and tls-alpn-01 challenges, with tls-alpn-01 tied to RFC 8737.

The interesting part of the feature list is how much of the recent ACME work it has picked up. It supports RFC 8738 for IP identifier validation, which is the change that makes issuing a certificate for a bare IP address possible rather than requiring a name. It supports RFC 8739 for short-term automatic certificate renewal, marked as experimental. It supports RFC 8823 for S/MIME certificates, also experimental, and RFC 9444 for subdomain validation, and RFC 9773 for renewal information.

Three draft specifications are supported as well, all experimental: draft-ietf-acme-profiles-01 for certificate profiles, draft-ietf-acme-dns-account-label-03 for DNS labelled with ACME account ID challenges, and draft-ietf-acme-dns-persist-01 for dns-persist-01 challenges.

The label experimental is doing real work in that list. It signals that the support exists but that the underlying drafts may still change, and in the case of a certificate authority, that the CA may not implement the extension at all.

The code base itself is described as mature and stable, with the first release in December 2015, and the project adheres to Semantic Versioning, so a 5.x version means the API has not been broken since 5.0.0.

## Any CA that speaks ACME, and the independence caveat

The list of supported certificate authorities is worth reading for what it implies rather than for the names themselves.

The library supports Actalis, Google Trust Services, Let's Encrypt, SSL.com, ZeroSSL, and all other CAs that comply with the ACME protocol of RFC 8555. That last clause is the important one. An ACME client talks a protocol, and any CA implementing that protocol should work, which is the whole point of the standardisation.

The readme attaches a caveat to the list: acme4j is an independent project that is not supported or endorsed by any of the CAs. That is a normal and correct statement for a client library, and it is worth reading as a fact about where the support boundary lies. If something breaks against a particular CA, the CA will point at its own documentation and the client project will point at the RFC, and you are the one debugging it.

That is also why the CA list is less of a compatibility statement than it looks. The features that vary between CAs are exactly the experimental ones. IP identifier validation depends on the CA choosing to issue for an IP identifier. Short-term renewal depends on the CA implementing the profile. Certificate profiles and the DNS account label challenges are drafts, so support is doubly conditional.

The dependency list is short and tells you what the client brings with it. Bouncy Castle for the cryptography, jose4j for the JSON web signature and JOSE work that the protocol needs, and slf4j for logging. The separate acme4j-smime module adds Jakarta Mail and Bouncy Castle for the S/MIME path.

The requirements are a JRE 17 or higher, which is a floor worth checking if the surrounding application runs on an older runtime, since an ACME client usually lives inside the service that needs the certificate.

## The challenge type is the decision that shapes your deployment

Everything else in this library is bookkeeping around the protocol, and the part that determines whether it works in your environment is which challenge you can satisfy.

The http-01 challenge requires the CA to fetch a file over HTTP from a well-known path on the host, which means the validation request has to reach the machine you are issuing for. Behind a load balancer or a CDN, that means making sure the validation path is routed to the right place.

The dns-01 challenge requires a TXT record, which means your certificate workflow needs the ability to write DNS. It is the only one of the three that works for a wildcard certificate, because a wildcard has no single host to serve a file from.

The tls-alpn-01 challenge is the one most people have not met. It validates by completing a TLS handshake using a special certificate presented on the validation port, and it exists because there are networks where plain HTTP on port 80 is blocked but TLS is not.

So the choice is a property of your network and of your DNS. If you can write DNS records, dns-01 is the most flexible. If you cannot, http-01 is usually available. And if neither works because of how the network is filtered, tls-alpn-01 is the fallback, at the cost of a slightly more involved setup.

The draft dns-persist-01 challenge is the interesting one to watch, since it is an attempt to make the dns-01 flow resumable, and the DNS account label draft is about tying the challenge to the ACME account for authorisation reasons. Both are experimental, and both point at the same underlying issue, that the DNS challenge is the one that needs coordination between two systems and it is therefore the fragile one.

## A multi-module Maven project with a separate example and integration suite

The repository layout is a Maven multi-module build, and the module names describe what a consumer actually uses.

There is acme4j-client, which is the module you depend on for the protocol itself, and acme4j-smime, the separate module for the S/MIME path with its Jakarta Mail and Bouncy Castle dependencies. There is acme4j-example, which is the module the readme points you at for a quick start, and acme4j-it, which is the integration test module. A pom.xml sits at the root and there is a src/ directory alongside the modules.

The distinction between the example and the integration tests is worth understanding. The readme points at the source code of an example for a quick start, and the online documentation covers the general usage. The integration module is the part that exercises the library against something resembling a real ACME server, and it is where a change to the protocol handling would be caught before it reached a release.

The build has continuous integration in two places, a .gitlab-ci.yml file and a .github/ directory, which is a pattern that usually means the project runs on both GitHub and a GitLab mirror. The readme points contributors to both a CodeFloe fork and the GitHub repository, and the project is developed on CodeFloe with GitHub as the second home, a hosting arrangement that reflects the author's preference for a forge built on Codeberg infrastructure.

The distribution channel is Maven Central under the group id org.shredzone.acme4j, and the badges at the top of the readme cover the build status and the Maven Central listing. The project also adheres to Semantic Versioning, so the major version tells you whether an upgrade is a breaking change, and the release history shows v4.0.0 in January 2026, v5.0.0 in March 2026 and v5.1.0 in April 2026, so a major version has landed roughly every few months.

## Where the operational risk actually sits

The library handles the protocol, and it does not handle the operations around it, and that is where a certificate deployment usually goes wrong.

The first point is that ACME is a protocol for automating issuance, not a guarantee of issuance. Every challenge has to be satisfied at the moment the CA tries it, and a DNS record that was not written, or a service that was not listening on the validation path, produces a failed order rather than a bad certificate. The library's job is to make the retry and the renewal mechanics correct, and it does that, but it cannot make your DNS provider write a TXT record.

The second point is renewal. Automatic renewal only works if the process that renews keeps running and keeps its account key. The library supports RFC 9773 for renewal information, which is the mechanism for telling relying parties when a certificate will be replaced, and short-term automatic certificate renewal under RFC 8739, which reduces the window in which an expired certificate breaks something, at the cost of a much more frequent issuance schedule. Whether that trade is worth it depends on how quickly your infrastructure can serve a new certificate, which is an infrastructure question rather than a client library one.

The third point is account management. The ACME account key is the identity for the relationship with the CA, and losing it means losing the ability to renew through that account. That is a key management concern, and it is one that a client library cannot solve for you.

The project is candid about its own documentation for these, and the readme points to the online documentation and to an example source file rather than trying to compress the operational guidance into a page. There is also a separate section for the S/MIME module, and a separate example application per use case, which is the shape you want when the S/MIME path needs Jakarta Mail in the classpath and the plain path does not.

## Conclusion

acme4j suits a Java service that has to obtain and renew certificates without shelling out to a certificate management tool, and that needs the newer ACME features, such as IP identifier validation, short-term certificates or S/MIME, that a simpler client will not have. It does not suit a non-Java stack, and it does not remove the operational work of proving domain control, since every challenge still needs a DNS record or a reachable endpoint. Before adopting it, read the online documentation and the example source, pick the challenge type your infrastructure can actually support, and check which of the experimental features your CA actually implements.

## FAQ

### What is acme4j and what protocol does it implement?

It is a Java client for the Automatic Certificate Management Environment protocol as specified in RFC 8555, helping you connect to an ACME server and perform all necessary steps to manage certificates. It is fully RFC 8555 compliant and requires a JRE 17 or higher.

### Which ACME challenges does acme4j support?

The http-01, dns-01 and tls-alpn-01 challenges, with tls-alpn-01 tied to RFC 8737. It also supports the dns-persist-01 challenge from draft-ietf-acme-dns-persist-01, which is marked as experimental.

### Which certificate authorities can acme4j talk to?

Actalis, Google Trust Services, Let's Encrypt, SSL.com, ZeroSSL, and all other CAs that comply with the ACME protocol of RFC 8555. The readme notes that acme4j is an independent project that is not supported or endorsed by any of the CAs.

### How do I add acme4j to a Java project?

It is built with Maven and the packages are on Maven Central under org.shredzone.acme4j. The runtime dependencies are Bouncy Castle, jose4j and slf4j, and the acme4j-smime module adds Jakarta Mail for the S/MIME certificate path. The readme points at the online documentation and at the example source for a quick start.

## Sources

- [License: Apache-2.0](https://github.com/shred/acme4j/blob/master/LICENSE)
- [Project website](https://acme4j.shredzone.org)
- [README](https://github.com/shred/acme4j/blob/master/README.md)
- [Releases](https://github.com/shred/acme4j/releases)
- [shred/acme4j on GitHub](https://github.com/shred/acme4j)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shred-acme4j
