proxy sjc [error][PU01] client problem: invalid authority

What does this error message mean, and how do I fix it?

My website has been down since yesterday when all I did was push a new version into production. I hadn’t touched any of the config settings, and my certificates are all valid.

Dockerfile:

ARG RUBY_VERSION=3.3.4
FROM ruby:$RUBY_VERSION-slim as base

# Rack app lives here
WORKDIR /app

# Update gems and bundler
RUN gem update --system --no-document && \
    gem install -N bundler


# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build gems
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential

# Install application gems
COPY Gemfile* .
RUN bundle install


# Final stage for app image
FROM base

# Run and own the application files as a non-root user for security
RUN useradd ruby --home /app --shell /bin/bash
USER ruby:ruby

# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=ruby:ruby /app /app

# Copy application code
COPY --chown=ruby:ruby . .

# Start the server
EXPOSE 8080
CMD ["bundle", "exec", "rackup", "--host", "0.0.0.0", "--port", "8080"]

Thanks.

Hey @fullstackplus

That’s likely a client sending an HTTP request with incorrect Host header.
When the proxy is doing httphttps redirect it needs to parse the Host header to extract the original authority. If the authority (Host) can’t be parsed, e.g. has some some characters that are not supposed to be there, the proxy will reply with “400 Bad Request” and drop this message into logs.

Thank you @pavel. The proxy certainly didn’t have problems doing the httphttps redirect prior to the last deployment. Like I mentioned before, none of my configuration settings were changed between the last deployment and the one before.

Any tips on fixing the issue?

Here’s the output of curl inspecting the Host header:

❯ curl -v https://fullstackplus.tech/
* Host fullstackplus.tech:443 was resolved.
* IPv6: (none)
* IPv4: 66.241.124.109
*   Trying 66.241.124.109:443...
* Connected to fullstackplus.tech (66.241.124.109) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=fullstackplus.tech
*  start date: Oct 31 23:25:43 2024 GMT
*  expire date: Jan 29 23:25:42 2025 GMT
*  subjectAltName: host "fullstackplus.tech" matched cert's "fullstackplus.tech"
*  issuer: C=US; O=Let's Encrypt; CN=E6
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://fullstackplus.tech/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: fullstackplus.tech]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: fullstackplus.tech
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 403
< content-type: text/plain
< x-content-type-options: nosniff
< set-cookie: rack.session=BAh7B0kiD3Nlc3Npb25faWQGOgZFVG86HVJhY2s6OlNlc3Npb246OlNlc3Npb25JZAY6D0BwdWJsaWNfaWRJIkVmYWUwZmEyYjEyODYzYjVkMWRhYTY4YzU2NjRjNzgyY2VkY2I4YjJjNDUxMWY4MTc2ZTgxZTk1YzI3NmM4OWE1BjsARkkiCWNzcmYGOwBGSSIxUEJWbEwtNWJ5eVBUU2ktZWVYbXB3NVhZTGRSTGprSFdDaVQ1T1UwcXdpOD0GOwBG; path=/; httponly
< content-length: 18
< date: Thu, 28 Nov 2024 12:38:58 GMT
< server: Fly/d42d3a7f1 (2024-11-25)
< via: 2 fly.io
< fly-request-id: 01JDSCG8H12JCFB6EH4SF9VHT2-ams
<
* Connection #0 to host fullstackplus.tech left intact
Host not permitted%  

@fullstackplus

That’s 403 Forbidden, not 400 Bad Request.
I’ve just tried to send a GET request to some random path on https://fullstackplus.tech/ and I see in the logs that your app replies with 403 Forbidden:

Nov 28, 2024 @ 12:44:37.022526533 66.241.124.109 - - [28/Nov/2024:12:44:37 +0000] “GET /some-random-path HTTP/1.1” 403 - 0.0007

1 Like

@pavel: this might be a Rack::Protection issue. For this app, I upgraded to Sinatra 4.1.0 from version 4.0.0 and that’s when the issue appeared.

I just needed to be certain that the erratic behavior isn’t caused by anything on Fly’s end before I go ask on Sinatra forums.

Thank you for helping me troubleshoot.

/V.

The error is caused by the addition of explicit Host Authorization handling in Sinatra 4.1.0. It is implemented as a Rack middleware, bundled with rack-protection, but not exposed as a default nor opt-in protection:

Settings to be tweaked:

And an example: