# JWS has no anti-replay nonce

**URL:** <https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324>\
**Category:** Help\
**Created:** [October 2, 2019, 9:59pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324 "2019-10-02T21:59:47Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![altasnet](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@altasnet](https://community.letsencrypt.org/u/altasnet)\
**Post date:** [October 2, 2019, 9:59pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/1 "2019-10-02T21:59:47Z")

</div>

I’m getting error when I try to register and accept terms. I’ve already check that I’m using just one IP address. I’m using version 0.6.5

# Using main config file /shared/dehydrated/config

declare – CA=“[https://acme-staging.api.letsencrypt.org/directory](https://acme-staging.api.letsencrypt.org/directory)”  
declare – CERTDIR="/shared/dehydrated/certs"  
declare – ALPNCERTDIR="/shared/dehydrated/alpn-certs"  
declare – CHALLENGETYPE=“http-01”  
declare – DOMAINS\_D=""  
declare – DOMAINS\_TXT="/shared/dehydrated/domains.txt"  
declare – HOOK="/shared/dehydrated/hook.sh"  
declare – HOOK\_CHAIN=“no”  
declare – RENEW\_DAYS=“30”  
declare – KEYSIZE=“2048”  
declare – WELLKNOWN="/shared/dehydrated"  
declare – PRIVATE\_KEY\_RENEW=“yes”  
declare – OPENSSL\_CNF="/etc/pki/tls/openssl.cnf"  
declare – CONTACT\_EMAIL=""  
declare – LOCKFILE="/shared/dehydrated/lock"

VERSION  
Dehydrated by Lukas Schauer  
[https://dehydrated.io](https://dehydrated.io/)

Dehydrated version: 0.6.5  
GIT-Revision: unknown

OS: BIG-IP 14.1.0.3 Build 0.0.6  
Used software:  
bash: 4.2.46(2)-release  
curl: curl 7.47.1  
awk: GNU Awk 4.0.2  
sed: sed (GNU sed) 4.2.2  
mktemp: mktemp (GNU coreutils) 8.22  
grep: grep (GNU grep) 2.20  
diff: diff (GNU diffutils) 3.3  
openssl: OpenSSL 1.0.2p-fips 14 Aug 2018

./dehydrated --register --accept-terms

- Generating account key…
- Registering account key with ACME server…
  - ERROR: An error occurred while sending post-request to [https://acme-staging.api.letsencrypt.org/acme/new-reg](https://acme-staging.api.letsencrypt.org/acme/new-reg) (Status 400)

Details:  
HTTP/2.0 400  
server:nginx  
date:Wed, 02 Oct 2019 21:15:32 GMT  
content-type:application/problem+json  
content-length:100  
cache-control:public, max-age=0, no-cache  
replay-nonce:0002\_xoIBQHkeneUKKhLjCGvLu2pNl-Me7aP-dTwuVkTtBU

{  
“type”: “urn:acme:error:badNonce”,  
“detail”: “JWS has no anti-replay nonce”,  
“status”: 400  
}

Error registering account key. See message above for more information.

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [October 2, 2019, 10:06pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/2 "2019-10-02T22:06:41Z")

</div>

Account registrations are completely disabled on [acme-staging.api.letsencrypt.org](http://acme-staging.api.letsencrypt.org) - though that does not explain the nonce error whatsoever.

What happens if you update to:

```
CA=https://acme-staging-v02.api.letsencrypt.org/directory

```

Can you also take the `sha256sum` of the `dehydrated` script? I’m surprised to see this in 0.6.5 …

---

<div class="post-metadata">

**Author:** ![altasnet](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@altasnet](https://community.letsencrypt.org/u/altasnet)\
**Post date:** [October 3, 2019, 1:02pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/3 "2019-10-03T13:02:49Z")

</div>

Hello Az! Thank you for your attention!

We get the same error:

- Generating account key…
- Registering account key with ACME server…
  - ERROR: An error occurred while sending post-request to [https://acme-staging-v02.api.letsencrypt.org/acme/new-acct](https://acme-staging-v02.api.letsencrypt.org/acme/new-acct) (Status 400)

Details:  
HTTP/2.0 400  
server:nginx  
date:Thu, 03 Oct 2019 13:00:21 GMT  
content-type:application/problem+json  
content-length:112  
cache-control:public, max-age=0, no-cache  
link:[https://acme-staging-v02.api.letsencrypt.org/directory](https://acme-staging-v02.api.letsencrypt.org/directory);rel=“index”  
replay-nonce:0001IFhLT1nTS2VScBoScffkJaVl81zs3XwVdXEchGF\_5MI

{  
“type”: “urn:ietf:params:acme:error:badNonce”,  
“detail”: “JWS has no anti-replay nonce”,  
“status”: 400  
}

Error registering account key. See message above for more information.

sha256sum ab5e8fb9acae9f938c6bba7becb7361d8927a975d17d357ae733106ac79d6105 dehydrated

---

<div class="post-metadata">

**Author:** ![cpu](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/cpu/32/84514_2.png) [@cpu](https://community.letsencrypt.org/u/cpu)\
**Post date:** [October 3, 2019, 2:06pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/4 "2019-10-03T14:06:25Z")

</div>

I wonder if Dehydrated is falling into the same trap a few of the other shell based ACME clients (getssl, acme.sh, etc) hit since the CDN switch: case sensitive HTTP header matching that fails with H2’s all-lowercase headers.

From an external perspective just based on the error messages it seems like behaviour that could happen if the code pulling the replay nonce from the HTTP response header from the ACME server didn’t fail when it couldn’t extract a nonce to use.

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [October 3, 2019, 7:54pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/5 "2019-10-03T19:54:58Z")

</div>

The HTTP/2 header case sensitivity was fixed in 0.6.3, which is what surprised me.

---

<div class="post-metadata">

**Author:** ![throw1008a](https://avatars.discourse-cdn.com/v4/letter/t/e480ec/32.png) [@throw1008a](https://community.letsencrypt.org/u/throw1008a)\
**Post date:** [October 8, 2019, 12:19pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/6 "2019-10-08T12:19:02Z")

</div>

Doing some testing, with dehydrated 0.6.3, I get the following on a cert that needs renewal:

```
 + Requesting new certificate order from CA...
 + ERROR: An error occurred while sending post-request to https://acme-v02.api.letsencrypt.org/acme/new-order (Status 400)

Details:
HTTP/2.0 400
server:nginx
date:Tue, 08 Oct 2019 12:13:22 GMT
content-type:application/problem+json
content-length:112
boulder-requester:34257164
cache-control:public, max-age=0, no-cache
link:<https://acme-v02.api.letsencrypt.org/directory>;rel="index"
replay-nonce:0001 [] V99NYWw

{
  "type": "urn:ietf:params:acme:error:badNonce",
  "detail": "JWS has no anti-replay nonce",
  "status": 400
}

```

Then in 0.6.4 and 0.6.5 I get:

```
+ Fetching account ID...
  + ERROR: An error occurred while sending post-request to https://acme-v02.api.letsencrypt.org/acme/new-acct (Status 400)

Details:
HTTP/2.0 400
server:nginx
date:Tue, 08 Oct 2019 12:16:36 GMT
content-type:application/problem+json
content-length:112
cache-control:public, max-age=0, no-cache
link:<https://acme-v02.api.letsencrypt.org/directory>;rel="index"
replay-nonce:0002 [...] RLKbE0UKE

{
  "type": "urn:ietf:params:acme:error:badNonce",
  "detail": "JWS has no anti-replay nonce",
  "status": 400
}

```

The version of cURL:

```
curl 7.47.1 (x86_64-redhat-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2p zlib/1.2.7 libidn/1.28 libssh2/1.4.3 nghttp2/1.31.1
```

---

<div class="post-metadata">

**Author:** ![throw1008a](https://avatars.discourse-cdn.com/v4/letter/t/e480ec/32.png) [@throw1008a](https://community.letsencrypt.org/u/throw1008a)\
**Post date:** [October 8, 2019, 12:25pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/7 "2019-10-08T12:25:54Z")

</div>

I added an extra configuration file with the following contents:

```
CURL_OPTS="--http1.1"

```

No longer seem to get the “JWS has no anti-replay nonce” error.

---

<div class="post-metadata">

**Author:** ![joe\_h\_punkt](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/joe_h_punkt/32/34430_2.png) [@joe\_h\_punkt](https://community.letsencrypt.org/u/joe_h_punkt)\
**Post date:** [October 8, 2019, 12:33pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/8 "2019-10-08T12:33:50Z")

</div>

I’m seeing the “JW has no anti-replay nonce” error since yesterday on a system with dehydrated 0.6.5 and curl 7.47.0 that doesn’t even have HTTP2 support.

not experiencing problems on the staging server though.

---

<div class="post-metadata">

**Author:** ![throw1008a](https://avatars.discourse-cdn.com/v4/letter/t/e480ec/32.png) [@throw1008a](https://community.letsencrypt.org/u/throw1008a)\
**Post date:** [October 8, 2019, 1:24pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/9 "2019-10-08T13:24:29Z")

</div>

Created:

- [https://github.com/lukas2511/dehydrated/issues/684](https://github.com/lukas2511/dehydrated/issues/684)

---

<div class="post-metadata">

**Author:** ![throw1008a](https://avatars.discourse-cdn.com/v4/letter/t/e480ec/32.png) [@throw1008a](https://community.letsencrypt.org/u/throw1008a)\
**Post date:** [October 8, 2019, 1:51pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/10 "2019-10-08T13:51:14Z")

</div>

@ [joe\_h\_punkt](https://community.letsencrypt.org/u/joe_h_punkt), what is the full version output of your cURL?

```
$ curl --version
curl 7.47.1 (x86_64-redhat-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2p zlib/1.2.7 libidn/1.28 libssh2/1.4.3 nghttp2/1.31.1
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets
```

---

<div class="post-metadata">

**Author:** ![joe\_h\_punkt](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/joe_h_punkt/32/34430_2.png) [@joe\_h\_punkt](https://community.letsencrypt.org/u/joe_h_punkt)\
**Post date:** [October 8, 2019, 1:53pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/11 "2019-10-08T13:53:00Z")

</div>

```
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets

```

Also it failed producing a SAN certificate with 99 hosts (as my production cert that failed first had 88 hosts in it) but succeeds with only 20 FQDN in it.

---

<div class="post-metadata">

**Author:** ![altasnet](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@altasnet](https://community.letsencrypt.org/u/altasnet)\
**Post date:** [October 8, 2019, 2:48pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/12 "2019-10-08T14:48:03Z")

</div>

Worked like a charm!!! Thank you so much!

My curl version:

curl 7.47.1 (x86\_64-redhat-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2p zlib/1.2.7 libidn/1.28 libssh2/1.4.3 nghttp2/1.31.1  
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp  
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM\_WB SSL libz HTTP2 UnixSockets

---

<div class="post-metadata">

**Author:** ![throw1008a](https://avatars.discourse-cdn.com/v4/letter/t/e480ec/32.png) [@throw1008a](https://community.letsencrypt.org/u/throw1008a)\
**Post date:** [October 8, 2019, 2:56pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/13 "2019-10-08T14:56:32Z")

</div>

This is a bandaide though (IMHO).

What in the code “broke” with the switch from HTTP/1.1 to HTTP/2. I would think/hope that the tranposrt layer would have no effect over the application layer data.

Doesn’t seem to help joe\_h\_punkt either.

---

<div class="post-metadata">

**Author:** ![joe\_h\_punkt](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/joe_h_punkt/32/34430_2.png) [@joe\_h\_punkt](https://community.letsencrypt.org/u/joe_h_punkt)\
**Post date:** [October 8, 2019, 5:39pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/14 "2019-10-08T17:39:19Z")

</div>

here is where it actually goes wrong: when connecting to `/acme/new-nonce` the TLS handshake failes and the client (dehydrated) goes on trying with an empty nonce. guess it’s still a bug within boulder or the CDN or should the client retry fetching the nonce in these cases?

[https://pastebin.com/2VWLpgth](https://pastebin.com/2VWLpgth)

edit: also guessing the other trending issues in this forum are actually the same error with the boulder/the CDN not handing out nonces and clients that aren’t equipped with dealing with that.

---

<div class="post-metadata">

**Author:** ![cpu](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/cpu/32/84514_2.png) [@cpu](https://community.letsencrypt.org/u/cpu)\
**Post date:** [October 8, 2019, 5:57pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/15 "2019-10-08T17:57:05Z")

</div>

> [@joe\_h\_punkt](#):
>
> guess it’s still a bug within boulder

There's no Boulder bug related to this. It sounds like it's the same problem with the CDN edge that is being investigated in other threads (e.g. [https://community.letsencrypt.org/t/curl-tcp-connection-reset-by-peer/](https://community.letsencrypt.org/t/curl-tcp-connection-reset-by-peer/) )

---

<div class="post-metadata">

**Author:** ![cpu](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/cpu/32/84514_2.png) [@cpu](https://community.letsencrypt.org/u/cpu)\
**Post date:** [October 8, 2019, 5:57pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/16 "2019-10-08T17:57:29Z")

</div>

> [@joe\_h\_punkt](#):
>
> should the client retry fetching the nonce in these cases?

Yes, definitely. &nbsp;

---

<div class="post-metadata">

**Author:** ![joe\_h\_punkt](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/joe_h_punkt/32/34430_2.png) [@joe\_h\_punkt](https://community.letsencrypt.org/u/joe_h_punkt)\
**Post date:** [October 8, 2019, 6:11pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/17 "2019-10-08T18:11:24Z")

</div>

thanks for the feedback. if Lukas Schauer doesn’t have time maybe i’ll give it a try.

FYI, it TLS handshakes fail not only at the nonce-retrieving stage (which I guess would be even stranger) but also earlier in the process (although not that often for me).  
[https://pastebin.com/GvpS89MY](https://pastebin.com/GvpS89MY)  
this happened while sending the signed request.

---

<div class="post-metadata">

**Author:** ![joe\_h\_punkt](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/joe_h_punkt/32/34430_2.png) [@joe\_h\_punkt](https://community.letsencrypt.org/u/joe_h_punkt)\
**Post date:** [October 9, 2019, 8:59am UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/18 "2019-10-09T08:59:15Z")

</div>

so the issue with the empty nonce is actually a small logic bug in dehydrated that has just been fixed in master (see ticket [https://github.com/lukas2511/dehydrated/issues/684](https://github.com/lukas2511/dehydrated/issues/684))

here is a quickfix that implements retry when connecting to the CDN failes  
[https://pastebin.com/igFHAp6D](https://pastebin.com/igFHAp6D)

---

<div class="post-metadata">

**Author:** ![lukas2511](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/lukas2511/32/30337_2.png) [@lukas2511](https://community.letsencrypt.org/u/lukas2511)\
**Post date:** [October 9, 2019, 5:16pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/19 "2019-10-09T17:16:23Z")

</div>

Just to be clear: The underlying issue hasn’t been completely fixed yet. This error occurs due to connection issues with the CA and there currently is no retry-logic in dehydrated. The only thing the last commit fixed should be the type of the error message, instead of failing with “no nonce” dehydrated should (at least in theory…) now notice the broken HEAD request and fail early with a correct error message, but I think there is another issue which again prevents this from working correctly. I’ll have to do some work on it, until then you can always just rerun the script, at least with ACME it at least kinda keeps the state and doesn’t have to rerun everything again.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/letsencrypt/original/3X/c/a/ca6c06ea1ea201324bba7048c6841ce60236468d.png) [@system](https://community.letsencrypt.org/u/system)\
**Post date:** [November 8, 2019, 5:16pm UTC](https://community.letsencrypt.org/t/jws-has-no-anti-replay-nonce/103324/20 "2019-11-08T17:16:32Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
