Newbie can't make cgi work

1. Caddy version (caddy version): v2.4.6

2. How I run Caddy:

a. System environment:

Ububtu 21.10

b. Command:

caddy run --config /etc/caddy/Caddyfile

c. Service/unit/compose file:

d. My complete Caddyfile or JSON config:

	order cgi last
} {
	root * /var/www/html/


	cgi /hello /usr/local/cgi-bin/hello

3. The problem I’m having:

I’m very new to this, and I wanted to test a simple cgi, but I can’t make it work.
The cgi module is installed, and I placed a simple bash file in /usr/local/cgi-bin that I named hello, following the guide here: cgi package - -, but all I get is HTTP ERROR 404

4. Error messages and/or full log output:

2022/03/25 16:19:53.730 INFO using provided configuration {“config_file”: “/etc/caddy/Caddyfile”, “config_adapter”: “”}
2022/03/25 16:19:53.734 INFO admin admin endpoint started {“address”: “tcp/localhost:2019”, “enforce_origin”: false, “origins”: [“”, “localhost:2019”, “[::1]:2019”]}
2022/03/25 16:19:53.734 INFO http server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS {“server_name”: “srv0”, “https_port”: 443}
2022/03/25 16:19:53.735 INFO http enabling automatic HTTP->HTTPS redirects {“server_name”: “srv0”}
2022/03/25 16:19:53.735 DEBUG http starting server loop {“address”: “[::]:443”, “http3”: false, “tls”: true}
2022/03/25 16:19:53.735 DEBUG http starting server loop {“address”: “[::]:80”, “http3”: false, “tls”: false}
2022/03/25 16:19:53.735 INFO http enabling automatic TLS certificate management {“domains”: [“”]}
2022/03/25 16:19:53.736 DEBUG tls loading managed certificate {“domain”: “”, “expiration”: “2022/06/23 14:57:50.000”, “issuer_key”: “”, “storage”: “FileStorage:/root/.local/share/caddy”}
2022/03/25 16:19:53.736 DEBUG tls.cache added certificate to cache {“subjects”: [“”], “expiration”: “2022/06/23 14:57:50.000”, “managed”: true, “issuer_key”: “”, “hash”: “901563658fa59628233c71c4eff86605fd38fdc30849a4948e08e0d4448d12a6”, “cache_size”: 1, “cache_capacity”: 10000}
2022/03/25 16:19:53.737 INFO autosaved config (load with --resume flag) {“file”: “/root/.config/caddy/autosave.json”}
2022/03/25 16:19:53.737 INFO serving initial configuration
2022/03/25 16:19:53.737 INFO tls.cache.maintenance started background certificate maintenance {“cache”: “0xc000656380”}
2022/03/25 16:19:53.737 INFO tls cleaning storage unit {“description”: “FileStorage:/root/.local/share/caddy”}
2022/03/25 16:19:53.738 INFO tls finished cleaning storage units
2022/03/25 16:21:15.751 DEBUG tls.handshake choosing certificate {“identifier”: “”, “num_choices”: 1}
2022/03/25 16:21:15.752 DEBUG tls.handshake default certificate selection results {“identifier”: “”, “subjects”: [“”], “managed”: true, “issuer_key”: “”, “hash”: “901563658fa59628233c71c4eff86605fd38fdc30849a4948e08e0d4448d12a6”}
2022/03/25 16:21:15.752 DEBUG tls.handshake matched certificate in cache {“subjects”: [“”], “managed”: true, “expiration”: “2022/06/23 14:57:50.000”, “hash”: “901563658fa59628233c71c4eff86605fd38fdc30849a4948e08e0d4448d12a6”}
2022/03/25 16:21:15.812 DEBUG http.handlers.file_server sanitized path join {“site_root”: “/var/www/html/”, “request_path”: “/hello”, “result”: “/var/www/html/”}

5. What I already tried:

6. Links to relevant resources:


Since you ordered cgi to go last, it’s not running until after file_server, which is a terminal handler (unless you enable the pass_thru mode). You should order cgi before file_server or filter which requests are handled by the file server.

See Caddyfile Directives — Caddy Documentation

1 Like

Thank you.

Alas, I did try to rearrange the directives, and change the order global option, with no change in behavior.
Also the guide says specifically to add order cgi last.

Does caddy not have fallbacks in case file_server fails and another directive has a match?

I don’t know why it says that. :man_shrugging: It will be different for everyone.

The line order in the Caddyfile (like, which line they are on) does not matter. It’s all about the defined order. (@francislavoie maybe we should have a Caddy subcommand that can print out the directive order, what do you think?)

What did you change the global option line to be?

It does, that’s exactly what pass_thru mode is.

1 Like

like so?

} {
	root * /var/www/html/

	file_server {

	cgi /hello /usr/local/cgi-bin/hello
1 Like

Yep, I think that should work!

1 Like

You still need to set an order though, because all directives from plugins don’t have a directive order assigned to them. It just doesn’t necessarily need to be last. You could set it to order cgi before file_server, then you don’t need to use pass_thru.

Adding pass_thru doesn’t seem to work:

run: adapting config using caddyfile: parsing caddyfile tokens for 'file_server': Caddyfile:9 - Error during parsing: unknown subdirective 'pass_thru'

But I tried changing the order again, and after fixing other unrelated errors got it to work.

So what was your final config? Sounds like your Caddyfile was structured improperly at first (was different from what you posted above).

I posted in the hope that you would correct my syntax.
This is what I ended up with:

	order cgi first
} {
	root * /var/www/html/


	cgi /hello /usr/local/cgi-bin/hello

The syntax you posted above was correct. What you ran must have been different.

Good job figuring it out :+1: Thanks for posting your working config for others.

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