Cronjob to renew cert via certbot-auto is failing

I’m getting an error from the cronjob I’ve setup to renew my letsencrypt cert.

Previously I’ve successfully received a cert and set it up on the site. I can also manually renew the cert with certbot-auto renew after ssh-ing into the server, and that works.

But my cronjob (below) fails, with the following error in the log.

17 3,15 * * * certbot-auto renew

Can anyone advise how I could fix this?

2017-02-27 18:13:29,307:DEBUG:certbot.main:Root logging level set at 20
2017-02-27 18:13:29,308:INFO:certbot.main:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2017-02-27 18:13:29,309:DEBUG:certbot.main:certbot version: 0.11.1
2017-02-27 18:13:29,309:DEBUG:certbot.main:Arguments: ['--standalone', '-m', 'ops@iqmi.ca', '-d', 'e', '--agree-tos', '--noninteractive']
2017-02-27 18:13:29,310:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#nginx,PluginEntryPoint#standalone,PluginEntryPoint#manual,PluginEntryPoint#webroot,PluginEntryPoint#apache,PluginEntryPoint#null)
2017-02-27 18:13:29,310:DEBUG:certbot.plugins.selection:Requested authenticator standalone and installer None
2017-02-27 18:13:29,656:DEBUG:certbot.plugins.selection:Single candidate plugin: * standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot.plugins.standalone:Authenticator
Initialized: <certbot.plugins.standalone.Authenticator object at 0x7fd6de020810>
Prep: True
2017-02-27 18:13:29,657:DEBUG:certbot.plugins.selection:Selected authenticator <certbot.plugins.standalone.Authenticator object at 0x7fd6de020810> and installer None
2017-02-27 18:13:29,663:DEBUG:certbot.main:Picked account: <Account(...)>
2017-02-27 18:13:29,664:DEBUG:root:Sending GET request to https://acme-v01.api.letsencrypt.org/directory.
2017-02-27 18:13:29,673:DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2017-02-27 18:13:29,893:DEBUG:requests.packages.urllib3.connectionpool:https://acme-v01.api.letsencrypt.org:443 "GET /directory HTTP/1.1" 200 352
2017-02-27 18:13:29,895:DEBUG:acme.client:Received response:
HTTP 200
Server: nginx
Content-Type: application/json
Content-Length: 352
Boulder-Request-Id: ...
Replay-Nonce: ...
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Mon, 27 Feb 2017 18:13:29 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Mon, 27 Feb 2017 18:13:29 GMT
Connection: keep-alive

{
  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",
  "new-authz": "https://acme-v01.api.letsencrypt.org/acme/new-authz",
  "new-cert": "https://acme-v01.api.letsencrypt.org/acme/new-cert",
  "new-reg": "https://acme-v01.api.letsencrypt.org/acme/new-reg",
  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"
}
2017-02-27 18:13:29,900:INFO:certbot.main:Obtaining a new certificate
2017-02-27 18:13:29,901:DEBUG:root:Requesting fresh nonce
2017-02-27 18:13:29,901:DEBUG:root:Sending HEAD request to https://acme-v01.api.letsencrypt.org/acme/new-authz.
2017-02-27 18:13:29,961:DEBUG:requests.packages.urllib3.connectionpool:https://acme-v01.api.letsencrypt.org:443 "HEAD /acme/new-authz HTTP/1.1" 405 0
2017-02-27 18:13:29,962:DEBUG:acme.client:Received response:
HTTP 405
Server: nginx
Content-Type: application/problem+json
Content-Length: 91
Allow: POST
Boulder-Request-Id: ...
Replay-Nonce: ...
Expires: Mon, 27 Feb 2017 18:13:29 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Mon, 27 Feb 2017 18:13:29 GMT
Connection: keep-alive


2017-02-27 18:13:29,962:DEBUG:acme.client:Storing nonce: ...
2017-02-27 18:13:29,962:DEBUG:acme.client:JWS payload:
{
  "identifier": {
    "type": "dns", 
    "value": "e"
  }, 
  "resource": "new-authz"
}
2017-02-27 18:13:29,966:DEBUG:root:Sending POST request to https://acme-v01.api.letsencrypt.org/acme/new-authz:
{
  "header": {
    "alg": "RS256", 
    "jwk": {
      "e": "AQAB", 
      "kty": "RSA", 
      "n": "..."
    }
  }, 
  "protected": "...", 
  "payload": "...", 
  "signature": "..."
}
2017-02-27 18:13:30,069:DEBUG:requests.packages.urllib3.connectionpool:https://acme-v01.api.letsencrypt.org:443 "POST /acme/new-authz HTTP/1.1" 400 109
2017-02-27 18:13:30,071:DEBUG:acme.client:Received response:
HTTP 400
Server: nginx
Content-Type: application/problem+json
Content-Length: 109
Boulder-Request-Id: ...
Boulder-Requester: ...
Replay-Nonce: ...
Expires: Mon, 27 Feb 2017 18:13:30 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Mon, 27 Feb 2017 18:13:30 GMT
Connection: close

{
  "type": "urn:acme:error:malformed",
  "detail": "DNS name does not have enough labels",
  "status": 400
}
2017-02-27 18:13:30,071:DEBUG:acme.client:Storing nonce: ...
2017-02-27 18:13:30,073:DEBUG:certbot.main:Exiting abnormally:
Traceback (most recent call last):
  File "/root/.local/share/letsencrypt/bin/letsencrypt", line 11, in <module>
    sys.exit(main())
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/certbot/main.py", line 882, in main
    return config.func(config, plugins)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/certbot/main.py", line 659, in obtain_cert
    action, _ = _auth_from_available(le_client, config, domains, certname, lineage)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/certbot/main.py", line 108, in _auth_from_available
    lineage = le_client.obtain_and_enroll_certificate(domains, certname)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/certbot/client.py", line 294, in obtain_and_enroll_certificate
    certr, chain, key, _ = self.obtain_certificate(domains)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/certbot/client.py", line 265, in obtain_certificate
    self.config.allow_subset_of_names)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/certbot/auth_handler.py", line 67, in get_authorizations
    domain, self.account.regr.new_authzr_uri)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/acme/client.py", line 228, in request_domain_challenges
    typ=messages.IDENTIFIER_FQDN, value=domain), new_authzr_uri)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/acme/client.py", line 208, in request_challenges
    new_authz)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/acme/client.py", line 685, in post
    return self._post_once(*args, **kwargs)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/acme/client.py", line 698, in _post_once
    return self._check_response(response, content_type=content_type)
  File "/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/acme/client.py", line 586, in _check_response
    raise messages.Error.from_json(jobj)
Error: urn:acme:error:malformed :: The request message was malformed :: DNS name does not have enough labels

certbot is trying to get a certificate for the hostname e. Yes, you read that correct, just an e. Obviously, that’s not going to work.

Somehow, somewhere, you’ve got that domain specified.

Furthermore, I’m actually not seeing certbot renew like log-entries? I would expect something about parsing files from /etc/letsencrypt/renewal/ and if the cert is or isn’t up for renewal. This looks like a normal certbot certonly --standalone -d e run.

Also, cronjobs most of the time run in a totally different environment than your regular SSH sessions. I’m surprised the certbot-auto command even runs without specifying a directory?

It might have been specified in the cli.ini file? (I’ve been meaning to make a pull request to discourage people from specifying domains there.)

I agree with the suspicion that somehow this is not the certbot-auto renew command running, but some other Certbot command running somehow (maybe from a different crontab file?).

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