Prevent cetrbot from failing with non-ascii characters in config?


I have a non-ascii urls on my website. Therefore I have rules like this in nginx:

location /абвгд {
    default_type text/html;

When I try to update my cetificate I get an error similar to this one:

Attempting to renew cert xxx from /etc/letsencrypt/renewal/ produced an unexpected error: ‘ascii’ codec can’t encode character ‘\uXXX’ in position XXX: ordinal not in range(128).

Changing my config to only include non-unicode characters is not an option, as nginx does matching based decoded path, i.e. percent-encoded path would not work (location /%D0%B0%D0%B1%D0%B2). Maybe there is way to force nginx to work with percent-encoded path, however from what I read on the forum it does not seem possible.

The only two work-arounds I see are:

  1. Temporary change the config file before updating. (Really ugly)
  2. Move non-unicode rules into another included file (not sure this would work even).

Is there maybe a way to allow certbot to survive at UTF8? I mean it’s 2018, and we have national domains and non-unicode urls. In older version of certbot this was working without problems.


Unfortunately the work on Certbot to fix this is still in progress.

One way to avoid this problem is simply not to use the nginx authenticator at all.

For example, using the webroot authenticator can form a viable basis of operation:

certbot certonly --webroot -w /var/www/html --deploy-hook "service nginx reload" \

There are a number of other ACME clients that don’t suffer from this defect, but they also generally do not modify your webserver configuration for you.

Edit: I tried escaping nginx with both urlencoding and \xFF notation, neither seems to be evaluated by nginx (or rather, they are interpreted literally).


Hi @idavydov

doesn’t it work if you use the utf-8 encoding with %?


This is the correct Ascii-sequence.

PS: Your sequence

is only


so it’s not complete and can’t work.


Hi @JuergenAuer,

Sorry this was the typo when asking this question. In the real test which I performed the url-encoded and non url-encoded versions where representing the same URL.

When I was trying to understand why’s that, I’ve discovered the following answer:

Another thing is that, as documented, the location matching is performed against a normalised URI


Thanks, @_az .

For the reference here’s the github issue:


Additionally from nginx documentation:

The matching is performed against a normalized URI, after decoding the text encoded in the “ %XX ” form, resolving references to relative path components “ . ” and “ .. ”, and possible compression of two or more adjacent slashes into a single slash.


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