Http reverse_proxy returned 404

1. The problem I’m having:

There are two handle_path of my Caddyfile, first is handle_path /2d/api/* and sencond is handle_path /2d/*

When I use HTTPS to request /2d/api/User/Info ,It respond right.
But when I use HTTP to request /2d/api/User/Info , It matched to /2d/, (I checked the debug message of caddy , and make sure it matched to /2d/ )
and respond with 404

2. Error messages and/or full log output:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

3. Caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

4. How I installed and ran Caddy:

ubuntu 22.04 ,and systemctl start caddy

a. System environment:

x86_64

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

myexample.com, http://myexample.com {

handle_path /2d/api/* {
                @options {
                        method OPTIONS
                }
                handle @options {
                        header Access-Control-Allow-Origin *
                        respond @options 204
                }
                header Access-Control-Allow-Credentials true
                header Access-Control-Allow-Headers Auth-Token,Content-Type,Access-Token
                rewrite * /api{uri}
                reverse_proxy http://127.0.0.1:3030
        }
        handle_path /2d/* {
                header Access-Control-Allow-Credentials true
                header Access-Control-Allow-Origin *
                root * /dist
                file_server
        }


}


5. Links to relevant resources:

And I tried to remove handle_path /2d/* , and request with HTTP again, and for this time , It matched to the right handle_path ,that is /2d/api/* , and respond right.

Also tried caddy v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=, same problem.

Please make requests with curl -v to show the behaviour you’re seeing. Please enable the debug global option and show Caddy’s logs after making requests. Please don’t skip any parts of the help topic template.

1、 caddy debug is enabled, and logs as this:

May 29 09:47:18 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324838.323505,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_ip":"120.46.167.42","remote_port":"58016","proto":"HTTP/2.0","method":"GET","host":"mapchang.com","uri":"/2d/api/User/Info","headers":{"User-Agent":["curl/7.68.0"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mapchang.com"}},"method":"GET","uri":"/User/Info"}
May 29 09:47:18 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324838.323542,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_ip":"120.46.167.42","remote_port":"58016","proto":"HTTP/2.0","method":"GET","host":"mapchang.com","uri":"/User/Info","headers":{"User-Agent":["curl/7.68.0"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mapchang.com"}},"method":"GET","uri":"/api/User/Info"}
May 29 09:47:18 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324838.3235888,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"127.0.0.1:3030","total_upstreams":1}
May 29 09:47:18 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324838.3253257,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"127.0.0.1:3030","duration":0.001705843,"request":{"remote_ip":"120.46.167.42","remote_port":"58016","proto":"HTTP/2.0","method":"GET","host":"mapchang.com","uri":"/api/User/Info","headers":{"User-Agent":["curl/7.68.0"],"Accept":["*/*"],"X-Forwarded-For":["120.46.167.42"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["mapchang.com"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mapchang.com"}},"headers":{"Expires":["Thu, 01 Jan 1970 00:00:00 GMT"],"X-Content-Type-Options":["nosniff"],"Content-Length":["48"],"Cache-Control":["no-cache, no-store, max-age=0, must-revalidate, value"],"Content-Type":["application/json; charset=utf-8"],"X-Frame-Options":["DENY"],"X-Request-Id":["403ec2cb-82fd-4994-b697-5d0cff0caed2"],"X-Xss-Protection":["1; mode=block"],"Date":["Mon, 29 May 2023 01:47:18 GMT"],"Access-Control-Allow-Origin":["*"],"Last-Modified":["Mon, 29 May 2023 01:47:18 GMT"]},"status":401}
May 29 09:47:21 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324841.1521153,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"127.0.0.1:3030","total_upstreams":1}
May 29 09:47:23 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324843.9803813,"logger":"http.handlers.rewrite","msg":"rewrote request","request":{"remote_ip":"120.46.167.42","remote_port":"41160","proto":"HTTP/1.1","method":"GET","host":"mapchang.com","uri":"/2d/api/User/Info","headers":{"User-Agent":["curl/7.68.0"],"Accept":["*/*"]}},"method":"GET","uri":"/api/User/Info"}
May 29 09:47:23 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324843.9804761,"logger":"http.handlers.file_server","msg":"sanitized path join","site_root":"/dist","request_path":"/api/User/Info","result":"/dist/api/User/Info"}
May 29 09:47:23 ecs-99f5 caddy[1610852]: {"level":"debug","ts":1685324843.9805243,"logger":"http.log.error","msg":"{id=1zef63n3j} fileserver.(*FileServer).notFound (staticfiles.go:601): HTTP 404","request":{"remote_ip":"120.46.167.42","remote_port":"41160","proto":"HTTP/1.1","method":"GET","host":"mapchang.com","uri":"/2d/api/User/Info","headers":{"User-Agent":["curl/7.68.0"],"Accept":["*/*"]}},"duration":0.000218108,"status":404,"err_id":"1zef63n3j","err_trace":"fileserver.(*FileServer).notFound (staticfiles.go:601)"}

I request 2 times。 first use https, and second with http.
For the first request , it’s proxied to 127.0.0.1:3030, and it’s right.
For the second request, it’s matched to "handle_path /2d/* ", and respond with 404, for /dist has no resources with path /api/User/Info

And curl -v result as follows:

with https:

*   Trying 121.36.14.85:443...
* TCP_NODELAY set
* Connected to mapchang.com (121.36.14.85) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=mapchang.com
*  start date: May  4 22:54:26 2023 GMT
*  expire date: Aug  2 22:54:25 2023 GMT
*  subjectAltName: host "mapchang.com" matched cert's "mapchang.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55d0e9775e30)
> GET /2d/api/User/Info HTTP/2
> Host: mapchang.com
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 401
< access-control-allow-credentials: true
< access-control-allow-headers: Auth-Token,Content-Type,Access-Token
< access-control-allow-origin: *
< alt-svc: h3=":443"; ma=2592000
< cache-control: no-cache, no-store, max-age=0, must-revalidate, value
< content-type: application/json; charset=utf-8
< date: Mon, 29 May 2023 01:47:18 GMT
< expires: Thu, 01 Jan 1970 00:00:00 GMT
< last-modified: Mon, 29 May 2023 01:47:18 GMT
< server: Caddy
< x-content-type-options: nosniff
< x-frame-options: DENY
< x-request-id: 403ec2cb-82fd-4994-b697-5d0cff0caed2
< x-xss-protection: 1; mode=block
< content-length: 48
<
* Connection #0 to host mapchang.com left intact
{"code":100202,"message":"Signature is invalid"}

and with http:

*   Trying 121.36.14.85:80...
* TCP_NODELAY set
* Connected to mapchang.com (121.36.14.85) port 80 (#0)
> GET /2d/api/User/Info HTTP/1.1
> Host: mapchang.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Origin: *
< Server: Caddy
< Date: Mon, 29 May 2023 01:47:23 GMT
< Content-Length: 0
<
* Connection #0 to host mapchang.com left intact

That doesn’t make any sense :thinking: I’m not able to replicate that behaviour.

Can you run caddy adapt --config /etc/caddy/Caddyfile --pretty, I’d like to see your JSON config if it somehow adapts to something different for some reason.

I exported a json config, but it is too big and too complex over 6000 lines
I checked it’s srvX of this host, didn’t find any abnormal config.

But finally after some tesing, I solved it by remove anoter useless handle directive.

This handle directive is very normal. Such as

handle /12345678 {
                reverse_proxy http://127.0.0.1:18000
}

And the number of chars of the route is the root cause.

I test it with /1234567 or any other route within 7 chars , it’s ok . And any other over 7 chars, it’s failed.

Please give a full Caddyfile that has the representative behaviour. I can’t tell what’s going on from just that alone.

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