Renew certificate, Parse failure

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. |, so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:

I ran this command: certbot renew

It produced this output: Processing /etc/letsencrypt/renewal/

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/", line 408, in init
self.configfile = configobj.ConfigObj(config_filename)
File "/usr/lib/python3/dist-packages/", line 1229, in init
self._load(infile, configspec)
File "/usr/lib/python3/dist-packages/", line 1318, in _load
raise error
File "", line None
configobj.ParseError: Invalid line ('/etc/letsencrypt/live/ > /etc/icecast2/bundle.pem && service icecast2 restart') (matched as neither section nor keyword) at line 19.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/", line 65, in _reconstitute
renewal_candidate = storage.RenewableCert(full_path, config)
File "/usr/lib/python3/dist-packages/certbot/", line 411, in init
"error parsing {0}".format(config_filename))
certbot.errors.CertStorageError: error parsing /etc/letsencrypt/renewal/
Renewal configuration file /etc/letsencrypt/renewal/ is broken. Skipping.

No renewals were attempted.

Additionally, the following renewal configurations were invalid:
/etc/letsencrypt/renewal/ (parsefail)

My web server is (include version): Icecast2

The operating system my web server runs on is (include version): ubuntu 18.04.5

My hosting provider, if applicable, is: My own VPS

I can login to a root shell on my machine (yes or no, or I don't know): Yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): No

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):?

What am I doing wrong? Please help.

As the message describes, that is not a valid line. Can you upload:

Do you know how that got into the renewal conf file? Did you put it there manually or was it part of a hook command when you created the cert initially?


This is the print of the file:

renew_before_expiry = 30 days

version = 0.27.0
archive_dir = /etc/letsencrypt/archive/
cert = /etc/letsencrypt/live/
privkey = /etc/letsencrypt/live/
chain = /etc/letsencrypt/live/
fullchain = /etc/letsencrypt/live/

Options used in the renewal process

account = dc44e70a3e0b4d5c70b687163dcf0cef
authenticator = webroot
webroot_path = /usr/share/icecast2/web,
server =
[[webroot_map]] = /usr/share/icecast2/web = /usr/share/icecast2/web
post_hook = cat /etc/letsencrypt/live/
/etc/letsencrypt/live/ > /etc/icecast2/bundle.pem && service icecast2 restart

Would you please do what I asked above? It would be helpful to see the file as it is - with line endings in place.

Also, you did not answer my question about how that line got there.


I put the lines under this by myself:

"post_hook = cat /etc/letsencrypt/live/
/etc/letsencrypt/live/ > /etc/icecast2/bundle.pem && service icecast2 restart"

Needs to be on one line. You keep showing it like it is two.

If you used the --post-hook option during the renew it would properly update the renewal conf for you.


When I make it one line, This is the output after the renew command:

Processing /etc/letsencrypt/renewal/

Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for
http-01 challenge for
Cleaning up challenges
Encountered exception during recovery:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/", line 75, in handle_authorizations
resp = self._solve_challenges(aauthzrs)
File "/usr/lib/python3/dist-packages/certbot/", line 126, in _solve_challenges
resp = self.auth.perform(all_achalls)
File "/usr/lib/python3/dist-packages/certbot/plugins/", line 83, in perform
File "/usr/lib/python3/dist-packages/certbot/plugins/", line 172, in _create_challenge_dirs
stat_path = os.stat(path)
FileNotFoundError: [Errno 2] No such file or directory: 'cat /etc/letsencrypt/live/ /etc/letsencrypt/live/ > /etc/icecast2/bundle.pem && service icecast2 restart'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/certbot/", line 108, in _call_registered
File "/usr/lib/python3/dist-packages/certbot/", line 310, in _cleanup_challenges
File "/usr/lib/python3/dist-packages/certbot/plugins/", line 222, in cleanup
FileNotFoundError: [Errno 2] No such file or directory: '/usr/share/icecast2/web/.well-known/acme-challenge/sqPhBFg0kV1ds48c-U7GGAfXCuxBliAh3tnrTCHrQMQ'
Attempting to renew cert ( from /etc/letsencrypt/renewal/ produced an unexpected error: [Errno 2] No such file or directory: 'cat /etc/letsencrypt/live/ /etc/letsencrypt/live/ > /etc/icecast2/bundle.pem && service icecast2 restart'. Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/ (failure)

All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/ (failure)

1 renew failure(s), 0 parse failure(s)

I think you want deploy_hook and not post_hook anyway. But, you will also need to disable hook validation. See this page in the docs for details of the hooks. There are also other ways of setting them up in hook folders.

  --post-hook POST_HOOK
                        Command to be run in a shell after attempting to
                        obtain/renew certificates. Can be used to deploy
                        renewed certificates, or to restart any servers that
                        were stopped by --pre-hook. This is only run if an
                        attempt was made to obtain/renew a certificate. If
                        multiple renewed certificates have identical post-
                        hooks, only one will be run. (default: None)
  --deploy-hook DEPLOY_HOOK
                        Command to be run in a shell once for each
                        successfully issued certificate. For this command, the
                        shell variable $RENEWED_LINEAGE will point to the
                        config live subdirectory (for example,
                        "/etc/letsencrypt/live/") containing the
                        new certificates and keys; the shell variable
                        $RENEWED_DOMAINS will contain a space-delimited list
                        of renewed certificate domains (for example,
                        "" (default: None)
                        Ordinarily the commands specified for --pre-
                        hook/--post-hook/--deploy-hook will be checked for
                        validity, to see if the programs being run are in the
                        $PATH, so that mistakes can be caught early, even when
                        the hooks aren't being run just yet. The validation is
                        rather simplistic and fails if you use more advanced
                        shell constructs, so you can use this switch to
                        disable it. (default: False)

Instead of using the certbot hooks you could also make your own script. Example of a "" :

sudo certbot renew (...)
cat (...)
echo (...)
and so on
1 Like

Thank you for the help but it did not werk in any way. This is too much tekst / info for me. I'm visual impaired. So can you help me anyway?

1 Like

I cannot reproduce your error. So I am not sure how to help you using very little text. Can you upload the renewal file?

If not, paste it here but mark it as preformatted text (from formatting menu or Ctrl-E)


Instead of two separate lines (which is out of syntax and fail):

Try is as one line:
post_hook = 'cat /etc/letsencrypt/live/ /etc/letsencrypt/live/ > /etc/icecast2/bundle.pem && service icecast2 restart'

Or perhaps, even better, as a script file:

1 Like

Yeah, it looks like they tried that Rudy and did not work. That is why I suggested disabling hook validation (for the 'not found' part). I agree though that should work - just puzzled why it seemed not to.


Yeah, I see that now :frowning:


Just note that --deploy-hook is used on the command line but renew_hook is the name used in the renewal conf file (sorry about that). This hook only runs after a cert is actually created and is better for this case.


Both operate in the same way - just at different times.
Once either is used in a sucessful issuance/renewal, the renewal config file is updated.
So either way would still need to call a script (for such complicated instructions).


Agree. They are combining the chain and private key and restarting the server so only needs to be done with fresh data. No great harm in doing it each try unless the server restart is disruptive. Yes, I checked, that server really needs the private key in a "bundle".


The trick here is that you can't do that in one line at the Linux (even as root) prompt.
You can say:
cat /some/file
But you can't say:
"cat /some/file"
BASH won't like it wrapped in any kind of quotes :frowning:


Hmmm. I tested this works:
post_hook = cat test.conf test.conf > test2.test && service nginx reload && echo test12-22

Also these work.

post_hook = 'cat test.conf test.conf > test2.test && service nginx reload && echo test12-22'
post_hook = "cat test.conf test.conf > test2.test && service nginx reload && echo test12-22"

Might Certbot remove the quotes during parse before issuing command?


You didn't see anything unusual in the LE logs?
Did the test2.test file get created each time?
[you should have used differently named files - one for each test]

What version of certbot did you use?


I looked at time stamps of the result file - always changed. Did not look in LE log but no error running command was displayed. I did get a display that the "service" command redirected to "systemctl" to confirm it ran as well (which was expected and handy to see).

I am using 1.21. OH! Maybe that's it - they are, um, much older!

Anyway, I'm out - g'night :slight_smile: