Error with socket on 2.5?

1. Caddy version (caddy version): 2.5.0

2. How I run Caddy: systemctl

a. System environment: Ubuntu 20.04.4

b. Command:

systemctl reload caddy

c. Service/unit/compose file:

# caddy.service
# For using Caddy with a config file.
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
# See for instructions.
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.


ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile


d. My complete Caddyfile or JSON config:

        email (MY EMAIL GOES HERE)
        #    admin off
        admin unix///var/run/caddy/caddy.sock

(php74) {
        php_fastcgi unix//run/php/php7.4-fpm.sock

(grav) {
        route {
                header Cache-Control max-age=3600
                header /assets/* Cache-Control max-age=16200000
                header /system/* Cache-Control max-age=16200000
                header /user/* Cache-Control max-age=16200000

        # Begin - Security
        # deny all direct access for these folders
        rewrite /(\.git|cache|bin|logs|backups|tests)/.* /403

        # deny running scripts inside core system folders
        rewrite /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ /403

        # deny running scripts inside user folder
        rewrite /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ /403

        # deny access to specific files in the root folder
        rewrite /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) /403

        respond /403 403
        ## End - Security

        # global rewrite should come last.
        try_files {path} {path}/ /index.php?_url={uri}&{query}

(secure) {
        header {
                # enable HSTS
                Strict-Transport-Security max-age=31536000;

                # disable clients from sniffing the media type
                X-Content-Type-Options nosniff

                # clickjacking protection
                X-Frame-Options DENY

                # keep referrer data off of HTTP connections
                Referrer-Policy no-referrer-when-downgrade

(wordpress) {
        # cache static content
        header /wp-content/cache/* Cache-Control max-age=14400

(logfile) {
        log {
                output file /srv/apps/{args.0}/logs/access.log

import /srv/config/caddy/enabled/*

3. The problem I’m having:

4. Error messages and/or full log output:

May 05 17:01:51 alycia caddy[3466]: {"level":"info","ts":1651770111.6170058,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":""}
May 05 17:01:51 alycia caddy[3466]: {"level":"warn","ts":1651770111.6285775,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile>
May 05 17:01:51 alycia caddy[3466]: {"level":"info","ts":1651770111.6288965,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":""}
May 05 17:01:51 alycia caddy[3466]: {"level":"warn","ts":1651770111.6351035,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile>
May 05 17:01:51 alycia caddy[3466]: reload: sending configuration to instance: performing request: Post "//%20/unixsocket/load": unsupported protocol scheme ""
May 05 17:01:51 alycia systemd[1]: caddy.service: Control process exited, code=exited, status=1/FAILURE
-- Subject: Unit process exited
-- Defined-By: systemd
-- Support:
-- An ExecReload= process belonging to unit caddy.service has exited.
-- The process' exit code is 'exited' and its exit status is 1.
May 05 17:01:51 alycia systemd[1]: Reload failed for Caddy.
-- Subject: A reload job for unit caddy.service has finished
-- Defined-By: systemd
-- Support:
-- A reload job for unit caddy.service has finished.
-- The job identifier is 3722 and the job result is failed.

5. What I already tried:

A few weeks ago, I tried to configure Caddy to bind admin API to a socket (see Caddyfile above, I also added RuntimeDirectory=caddy to service file to create a permissionned directory at launch. At that time I had Caddy 2.4.6 and everything worked fine.

I recently updated to Caddy 2.5.0, and trying to reload config through systemctl doesn’t work anymore as you can see above from journalctl -xe output

Note that my Caddyfile (and imported caddyfiles from /srv) should all be formatted correctly as they were ok before the update and didn’t change from the time I set up socket and now.

I looks like Caddy is not able to handle sockets in newest version ? Any clue on that ?


6. Links to relevant resources:

Will you be able to give this a shot: Should `enforce_origin` and `origins` work over the unix socket? - #2 by IndeedNotJames

I had no idea people were even using this feature :man_facepalming:

You can’t use regexp in inline matchers, because the inline matcher uses the simple path matcher.

If you need regexp, then use a named matcher with path_regexp:

You also don’t need to rewrite then respond. Just directly respond according to the matcher.

Don’t use systemctl status caddy to read your logs, they get truncated. Notice the > at the end of lines. Instead, use the command mentioned here to read your logs:

For the unix socket issue, unfortunately a bug was introduced in v2.5.0, it’s fixed here:

I guess for now, stick with v2.4.6, or build from the master branch. Sorry! It’ll land in v2.5.1.


Thank you all. I searched a bit before posting but couldn’t find anything that this bug was reported… Should have searched deeper!

As this is mainly for tests purpose (I actually host a few personal websites but that are not critical at all), I will try maybe to build the latest version with xcaddy, that will give me a chance to explore that part.

These are directives that were provided with Grav CMS I took and pasted without giving them a shot (but still must admit I didn’t know about pat/path_regexp matchers…). I understand about the matcher, I should define it first then use it in rewrite/respond ou whatever… But still, it works like this actually… But I don’t understand about using only respond. From what I understand, rewrite is used first to “redirect” to the error page, then respond sends the error code? respond can only show a text (body) and not a particular page?

1 Like

2.5.1 is out now and let me/us know if you still face the issue

1 Like


Well I guess they didn’t test them, because it definitely won’t work as-is.

Yep, that’s right. You define a named matcher (i.e. something starting with @ followed by the name) which has a path_regexp matcher inside of it, then you apply that named matcher to a directive.

Yeah the config will load, but it won’t work, and they will never match anything. The path matcher is essentially comparing the string as-is, it doesn’t evaluate the regular expressions.

Now that I think of it, it’s possible Grav was showing Caddy v1 config, not Caddy v2. Rewrites and matchers are done differently now, in Caddy v2.

It’s not a redirect, it’s a rewrite. Those are different concepts. A redirect is a special kind of HTTP response which has a Location header, which tells the client to make a new request to the URL in the Location header.

A rewrite is internal to the server; the request’s URI (path + query) is modified before other handlers use it.

The config you had was doing a rewrite to /403 as a “special path” and then re-matching on /403 later to write a response.

The rewrite isn’t necessary, you can skip that intermediary step completely and just directly write the 403 response.

That’s right. If you want to show an error page, I recommend you use the error directive to trigger an error, then use handle_errors to handle particular error codes and use file_server to serve the error page. There’s an example in the docs:

1 Like