ACME v1 endpoints giving 400?

Hello,

We’re suddenly seeing a number of HTTP 400 errors on new-reg requests to the v1 API.

Request body (pre-JWS): {"resource":"new-reg"}

Response headers (400 Bad Request):

  • Date: Tue, 24 Sep 2019 13:44:29 GMT
  • Server: nginx
  • Connection: close
  • Content-length: 150
  • Content-type: text/html

Response body:

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

This was from IPv4 184.94.197.2, but it’s happening on many of our servers (and our clients’ servers).

Please advise? We haven’t changed our implementation. This problem didn’t appear until last night, a few hours after we received notice of the recent CDN change.

Thank you!

I note that the error response is a plain HTTP 400, not an ACME error. That doesn’t seem right …

What are the request headers?

Looks like what we’re sending is:

                         'content-length' => 978,
                         'content-type' => 'application/octet-stream',
                         'host' => 'acme-v01.api.letsencrypt.org',
                         'user-agent' => 'Cpanel-HTTP-Client/1.0'

Does the new setup have a problem with the Content-Type?

(UPDATE: That doesn’t appear to be the case, as another implementation I use that continues to work sends the same header.)

It appears the new CDN rejects post (rather than POST) as an HTTP method. When we make that change it continues to work.

Thanks for the report @FGasper, we’re looking into it.

2 Likes

I did some digging and found out why some clients/subscribers began seeing 400 messages after the CDN swap.

The HTTP/1.1 RFC RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content and by association the HTTP/2 RFC RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2) states

HTTP was originally designed to be usable as an interface to
distributed object systems. The request method was envisioned as
applying semantics to a target resource in much the same way as
invoking a defined method on an identified object would apply
semantics. The method token is case-sensitive because it might be
used as a gateway to object-based systems with case-sensitive method
names.

A side-effect of the API CDN switch from Akamai to CloudFlare is that Akamai can no longer rewrite the request methods from lowercase to uppercase. I've not found explicit documentation that Akamai was doing that, but given your report I feel like there's a pretty good chance that it was happening. Our loadbalancer should be properly following these RFCs and rejecting the lowercase methods post, get, head, etc per https://github.com/nginx/nginx/blob/master/src/http/ngx_http_core_module.c#L4329-L4345.

2 Likes

@Phil Shouldn’t it fail the request with 405 (Method Not Allowed)?

@FGasper
I’m still digging through Nginx source code, but am no C coder. I got my initial hunch from this stackoverflow post.

Ah. Actually per that thread, it should be 501, not 400. MDN agrees.

(That seems kind of awkward, though … 5xx responses are usually “this failed, and it’s my fault” … which isn’t the case with a post request. Eh well.)

Anyway, thank you.

2 Likes

Hello,

Problem solved

1 Like

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