How to Set Up HTTP Redirects With Pangolin
Pangolin 1.25 added redirects. A redirect takes a request for one URL and answers it with a 307 or 308 pointing the client somewhere else. You can use one to retire an old hostname, send the bare domain to www, move a section of a site to a new path, or route a single path on an existing resource to a different app.
Before redirects, doing this meant running a separate web server or editing proxy config by hand just to issue the hop. Now it is a form in the dashboard under Settings > Redirects, and the redirect is served by the same proxy that already fronts your resources.
This guide follows the walkthrough in the video below, then covers path matching, rewrites, and priority in more detail.
Domain or Resource
Every redirect attaches to one of two things, and the choice decides which hostname it listens on.
A domain-attached redirect listens on a hostname built from one of your organization's domains plus an optional subdomain. Leave the subdomain empty to use the base domain itself. There does not need to be a resource on that hostname. Pangolin provisions a certificate for the host, and on self-hosted installs you can turn SSL off if you want plain HTTP. On Pangolin Cloud, HTTPS is always on. Deleting the domain deletes its redirects, but deleting or disabling a resource on the same hostname leaves the redirect alone.
A resource-attached redirect listens on the full hostname of an existing public resource, including wildcards if the resource uses them. TLS follows the resource. Requests that match the redirect get sent away, and every other request goes to the resource as usual. If the resource is disabled or has no domain, the redirect is inactive, and if the resource is deleted, the redirect goes with it.
Pick a domain when the hostname has nothing behind it, or when you want the redirect to outlive whatever resource happens to be on that host. Pick a resource when you want a few paths on a live app to go somewhere else.
Step by Step
The video starts from an empty organization so there is something to redirect to. If you already have a working resource, skip to step 3.
1. Create a site and a test app
Go to the Sites tab, click Add Site, and give it a name like test-redirect. Pangolin shows a command to start the site connector. Copy it, click Create Site, and run the command on the machine you want to expose. In the video this is a laptop.
On the same machine, start something to look at. The video uses a small HTTP server on localhost:8000 that prints back the request and its headers, which makes it easy to see what arrived after a redirect. Any local web server works.
2. Create a public resource
Go to Resources and click Add Resource. Choose HTTP, name it test, set the subdomain to test, and add a target on the test-redirect site pointing at localhost:8000. After you create it, test.example.com loads the same page as localhost:8000, with a few extra headers added by the proxy.
3. Redirect a hostname to another URL
Go to Redirects and click Add Redirect. Name it redirect-one and leave it enabled.
Attach it to a Domain, pick your domain, and enter redirect as the subdomain. For the destination, enter any origin. The video uses an external site to show that the destination can be anywhere:
| Field | Value |
|---|---|
| Attach to | Domain |
| Subdomain | redirect |
| Destination | https://example.org |
| Match path | (empty) |
Leave the match path empty so every request to redirect.example.com is redirected. Save it, open redirect.example.com in a browser, and you land on example.org.
To point the same hostname at your own resource instead, open the redirect again, change the destination to https://test.example.com, and click Save Settings. The next visit to redirect.example.com ends up at the test app.
4. Redirect one path on a resource
Create a second redirect called redirect-two. This time attach it to a Resource and choose test.
Since the resource already serves the whole hostname, you usually want to match a path here rather than everything. Say all of test.example.com should stay on the test app except /api, which should go elsewhere:
| Field | Value |
|---|---|
| Attach to | Resource (test) |
| Path match type | Prefix |
| Match path | /api |
| Destination | https://example.org |
Now test.example.com/ still loads the app. A request to test.example.com/api/v1 is redirected to https://example.org/api/v1. The path came along because, by default, Pangolin keeps the original path and query string and only swaps the origin.
5. Check the logs
Redirects show up in the same request logs as resources. Go to Logs & Analytics and open HTTP Request Logs. Each row shows who made the request, why it was allowed, and where it went, so the /api/v1 request from step 4 appears with its redirect target next to it.
How Matching Works
A request matches a redirect when its Host header equals the redirect's listen host and its path matches the redirect's path rule. A redirect with no path rule matches every path on the host.
| Match type | What matches |
|---|---|
| Exact | The path equals the match path |
| Prefix | The path starts with the match path as a whole segment, so /products matches /products/shoes but not /productsforsale |
| Regex | The path matches the regular expression |
When a redirect and a resource share a hostname, Pangolin checks the redirect first. This includes checking it before the resource's authentication, so a visitor who hits a matching path is redirected without being asked to log in. That is useful for sending a public path like /status to a status page, but keep it in mind before attaching a broad redirect to a protected resource.
Rewriting the Path
The destination field takes an origin only: scheme, host, and an optional port, such as https://example.com or https://example.com:8443. Paths, query strings, and fragments do not go in that field. The URL the client receives is built like this:
destination origin + rewritten path + original query string
With no rewrite set, the rewritten path is the original path. To change it, choose a rewrite type:
| Rewrite type | Effect |
|---|---|
| Exact | Replace the whole path with a fixed one |
| Prefix | Replace the matched prefix and keep the rest |
| Regex | Substitute using the match pattern, with $1, $2 for groups |
| Strip prefix | Remove the matched prefix, and optionally add a new one |
If you only want to change the path and keep visitors on the same host, set the destination to Same Domain as Source.
A few examples:
To move a section of a site, take a resource at docs.example.com, match on prefix /guides, rewrite with type Prefix to /tutorials, and use Same Domain as Source. /guides/install becomes /tutorials/install.
To split an old path onto its own host, use app.example.com, match prefix /legacy, set the destination to https://legacy.example.com, and strip the prefix. /legacy/reports?id=4 becomes https://legacy.example.com/reports?id=4.
Regex on both sides can reorder parts of a URL. This one moves /blog/2020/post to /archive/post-2020:
| Field | Value |
|---|---|
| Path match type | Regex |
| Match path | ^/blog/(\d+)/(.*)$ |
| Rewrite type | Regex |
| Rewrite path | /archive/$2-$1 |
Substitution follows the same rules as JavaScript's String.replace. If you pair a Prefix match with a Regex rewrite, whatever comes after the prefix is available as $1, so matching /old and rewriting to /new$1 turns /old/x into /new/x.
Temporary or Permanent
Redirects are temporary by default and return 307. Browsers do not hold on to a 307, so you can change the destination later and visitors pick up the change right away.
Turn on Permanent to return 308 instead. Browsers and search engines may cache a 308 and stop asking, which is what you want for a hostname you have retired for good, and a problem if you change your mind. Use temporary while testing and switch once the destination is settled.
Both codes keep the original request method, so a POST to the old URL is still a POST at the new one.
On self-hosted installs, permanent redirects need Badger v1.8.0 or newer. The 1.25 migration updates Badger when it finds the Traefik config in the standard location. Otherwise, update it by hand.
Priority
Each redirect has a priority from 1 to 1000, and higher numbers are checked first. Redirects always sit in front of resources on the same host regardless of the number, so priority only matters when two or more redirects could match the same request. For example, give an exact match on /api/health a higher priority than a prefix match on /api so the health check goes to its own destination.
FAQ
Do I need a resource or a site to create a redirect?
Not for a domain-attached redirect. It listens on a hostname from one of your domains whether or not a resource uses it. The video creates a site and resource only so there is a local app to redirect to. Resource-attached redirects need an existing public resource with a domain.
Does a redirect on a protected resource skip authentication?
For requests that match it, yes. Pangolin evaluates redirects before resource authentication, so a matching request is redirected without a login prompt. Requests that do not match the redirect still go through the resource's normal authentication.
Is the query string kept?
Yes. The original query string is always appended to the final URL, after any path rewrite.
Can I put a path in the destination?
No. The destination is an origin only. Use a path rewrite (Exact, Prefix, Regex, or Strip prefix) to control the path on the other side.
What status codes does Pangolin return?
307 for temporary redirects and 308 for permanent ones. Both preserve the HTTP method and body.
How do I redirect the bare domain to www?
Create a domain-attached redirect on your base domain with the subdomain left empty, leave the match path empty, and set the destination to https://www.example.com. The path and query string carry over unchanged. Turn on Permanent once you have confirmed it works.
Can I see which requests were redirected?
Yes. Redirected requests appear in Logs & Analytics > HTTP Request Logs alongside resource requests, with the destination they were sent to.
Is Pangolin open source?
Yes. Pangolin is open source and self-hostable. You can deploy the whole platform yourself, use Pangolin Cloud, or mix hosted and self-hosted components. Redirects are available in both.
See Also
- Redirects docs: the full reference for attachments, matching, rewrites, and priority
- Pangolin 1.25 release notes: redirects shipped alongside mTLS on public resources and roles on machine clients
- Domains: add and verify the domains that redirects and resources listen on
- HTTP/HTTPS public resources: configuration reference for the resources a redirect can attach to
- Installing a site connector: set up the tunnel used in step 1
Pangolin is an open-source Secure Access Service Edge (SASE) platform built on WireGuard® that unifies modern networking and security for teams connecting to apps, infrastructure, and AI workloads. Designed as an open, self-hostable alternative to complex legacy suites, Pangolin brings together a zero-trust VPN, zero-trust reverse proxy, privileged access management, and an identity-aware AI gateway under a single identity and policy model. Whether deployed on-premises using a lightweight user-space connector or managed via Pangolin Cloud, it gives organizations transparent, auditable, and frictionless control over their entire digital footprint.
Keep reading
- How to Require Client Certificates (mTLS) on a Pangolin Resource
How to Require Client Certificates (mTLS) on a Pangolin ResourceRequire a certificate signed by your own CA before anyone can reach a Pangolin public resource. This guide covers generating a CA with OpenSSL, uploading it to Pangolin, and connecting with curl and Chrome.
- Node2Shell: Protect Self-Hosted Apps from CVE-2026-111497
Node2Shell: Protect Self-Hosted Apps from CVE-2026-111497Node2Shell (CVE-2026-111497) is a high-severity Brotli flaw in Node.js that can allow remote code execution. Patch the runtime, then keep private apps behind auth or fully off the internet with an identity-based VPN and reverse proxy.
- PHP2Shell: Protect Self-Hosted Apps from CVE-2026-109618 and CVE-2026-109619
PHP2Shell: Protect Self-Hosted Apps from CVE-2026-109618 and CVE-2026-109619PHP2Shell (CVE-2026-109618, CVE-2026-109619) is under active exploit. Patch PHP, then keep private apps behind auth or fully off the internet with an identity-based VPN and reverse proxy.