Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cdn/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ description: Latest updates and improvements to the CDN.
rss: true
---

<Update label="2026-07-31" tags={["New"]}>
## IP Family Policy for Pull Zones

Pull Zones now support an IP Family Policy that controls which address families (IPv4, IPv6, or both) are advertised and which edge servers are eligible to serve the zone. Four policies are available: IPv4 Only, Dual Stack (default), Dual Stack Prefer IPv6, and IPv6 Only. Token authentication IP locking now supports IPv6 addresses, binding at the client's `/64` prefix. Enabling Token IP Validation pins the zone to a single address family automatically. [Learn more](/cdn/ip-family-policy)
</Update>

<Update label="2026-07-14" tags={["Improvement"]}>
## HTTP validation for Seamless Domain Migration

Expand Down
2 changes: 2 additions & 0 deletions cdn/connectivity.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ When users connect to bunny.net, DNS responses are generated based on the capabi

This approach ensures optimal compatibility while allowing IPv6-capable locations to serve traffic natively over IPv6.

Each Pull Zone can override this default behavior with an [IP Family Policy](/cdn/ip-family-policy), which controls whether we advertise IPv4, IPv6, or both, and whether routing prefers IPv6-capable locations.

## Origin Connectivity

We support both IPv4 and IPv6 connections to your origin servers.
Expand Down
101 changes: 101 additions & 0 deletions cdn/ip-family-policy.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
title: IP Family Policy
sidebarTitle: IP Family Policy
description: Control which IP address families your Pull Zone advertises and which edge servers are eligible to serve it.
---

The **IP Family Policy** of a Pull Zone controls which IP address families bunny.net advertises for your CDN hostnames, and which edge servers are eligible to serve them.

The policy affects the DNS answers returned for your Pull Zone hostname (`*.b-cdn.net`, custom hostnames, and hostnames [accelerated through Bunny DNS](/cdn/cdn-acceleration)):

- **A records** advertise an IPv4 address of the selected edge server.
- **AAAA records** advertise an IPv6 address of the selected edge server.
- **HTTPS (SVCB) records** carry `ipv4hint` and `ipv6hint` values, along with matching A and AAAA records in the additional section.

## Available policies

| Policy | Answers returned | Edge server selection |
| ------ | ---------------- | --------------------- |
| **IPv4 Only** | A only | Unrestricted |
| **Dual Stack** (default) | A, plus AAAA when the selected server has IPv6 | Unrestricted |
| **Dual Stack, Prefer IPv6** | A, plus AAAA when the selected server has IPv6 | IPv6-capable servers preferred |
| **IPv6 Only** | AAAA only | IPv6-capable servers only |

## IPv4 Only

Only IPv4 is advertised. AAAA records are never returned, even when the serving edge location supports IPv6, and HTTPS records contain an `ipv4hint` only.

Edge server selection is unaffected: all eligible locations are available, regardless of their IPv6 capability.

Use this policy when you require every request to arrive over IPv4, or when your clients or intermediate networks have known IPv6 problems. It is also the safest choice when something keys on the client's address, such as [IP-locked tokens](#token-authentication-and-ip-locking), rate limits, or allowlists, since a dual-stack client can otherwise switch family between requests.

## Dual Stack

The default policy. IPv4 is always advertised, and IPv6 is advertised whenever the edge server chosen for the request has an IPv6 address.

- **A queries** return the IPv4 address of the selected server.
- **AAAA queries** return the IPv6 address of the selected server, if it has one. If it doesn't, the answer is empty (NODATA) and the client uses IPv4.
- **HTTPS queries** return both `ipv4hint` and `ipv6hint` when both families are available.

Routing is not biased in any way. The nearest and least loaded location is selected exactly as it would be for an IPv4-only zone, and IPv6 is used opportunistically when that location supports it.

<Note>
Because the Standard Network supports IPv6 on a best-effort basis, a Dual Stack zone may return AAAA records for some clients and not others depending on which Point of Presence serves them. See [Connectivity](/cdn/connectivity) for network tier details.
</Note>

## Dual Stack, Prefer IPv6

Both address families are still advertised exactly as with Dual Stack, but routing is biased: IPv6-capable edge servers are preferred over IPv4-only ones, even when an IPv4-only location is closer to the client.

This maximizes the share of your traffic delivered over IPv6, at the cost of potentially routing some users to a more distant Point of Presence.

It is also the best option when something downstream can only reach you over IPv6, such as an IPv6-only network or a service that pulls from your Pull Zone without IPv4 connectivity. By steering requests to IPv6-capable locations, this policy does its best to guarantee that an AAAA answer is available, while still returning A records so IPv4 clients keep working. **IPv6 Only** makes that guarantee absolute, but returns nothing at all when no IPv6-capable location is available.

The bias is relaxed if the client is known to be IPv4. If EDNS Client Subnet tells us the client's address is IPv4, there is no benefit in preferring an IPv6-capable location, so selection falls back to normal distance and load based routing. AAAA queries keep the bias regardless, since only IPv6-capable clients act on an AAAA answer.

<Warning>
Preferring IPv6 can route users to a Point of Presence that is not the closest one available. On the Standard Network, where IPv6 coverage is still expanding, this may measurably increase latency for users in regions without IPv6-enabled locations.
</Warning>

## IPv6 Only

Only IPv6 is advertised, and only IPv6-capable edge servers are eligible to serve the zone.

- **AAAA queries** return the IPv6 address of the selected server.
- **A queries** return an empty answer with the zone's SOA record. No IPv4 address is ever advertised, even to a client that asks for one.
- **HTTPS queries** contain an `ipv6hint` only, with no additional A record.
- If no IPv6-capable edge server is available for the request, the response is empty, it will never fall back to IPv4.

<Warning>
An IPv6 Only Pull Zone is unreachable for IPv4-only clients, which still make up a substantial share of global traffic. Only use this policy when you control every client that connects, such as an internal or machine-to-machine workload.
</Warning>

## Token authentication and IP locking

[IP locking](/cdn/security/token-authentication/advanced#ip-locking) binds a token to the client IP address you sign it with, and rejects any request arriving from a different address. The signed address and the address the request actually arrives from must therefore be in the same family. On a zone reachable over both families, a client can be handed an address in one family while your token was signed for the other, and every such request fails validation.

To prevent that, enabling **Token IP Validation** on a Pull Zone pins the zone to a single address family:

| IP Family Policy | Effective policy with Token IP Validation enabled |
| ---------------- | ------------------------------------------------- |
| IPv4 Only | IPv4 Only |
| Dual Stack | IPv4 Only |
| Dual Stack, Prefer IPv6 | IPv4 Only |
| IPv6 Only | IPv6 Only |

In other words, token IP validation forces IPv4 Only unless you have explicitly chosen **IPv6 Only**, which is always respected. Sign the family your zone serves: IPv4 addresses in the default case, IPv6 addresses when the policy is IPv6 Only.

<Note>
Both IPv4 and IPv6 addresses can be signed. IPv4 binds either the exact address or a `/24`, and IPv6 binds the client's `/64` prefix. See [IP locking](/cdn/security/token-authentication/advanced#ip-locking) for the exact matching rules.
</Note>

## Choosing a policy

- **Leave it on Dual Stack** unless you have a specific reason not to. It serves IPv6 wherever it's available without ever compromising routing quality.
- **Choose Dual Stack, Prefer IPv6** when maximizing IPv6 delivery matters more than the last few milliseconds of latency, or when a downstream service can only reach you over IPv6 and you need AAAA answers wherever possible without losing IPv4 clients.
- **Choose IPv4 Only** when something keys on the client's IPv4 address, such as IP-locked tokens, rate limits, or allowlists, or when your clients' IPv6 support is unreliable. A Pull Zone with [token IP validation](#token-authentication-and-ip-locking) falls back to this policy automatically.
- **Choose IPv6 Only** only for closed, fully IPv6-capable client populations, or when every connection must arrive over IPv6 so that IP-locked tokens can be signed against IPv6 addresses.

<Note>
IP Family Policy applies to inbound connectivity, meaning how clients reach the CDN. Connectivity from the edge to your origin is negotiated separately and is described in [Connectivity](/cdn/connectivity).
</Note>
26 changes: 22 additions & 4 deletions cdn/security/token-authentication/advanced.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,29 @@ Signing with `token_path=/videos/stream1/` allows access to all files in that di

IP locking binds a token to a specific client IP address. Any request from a different IP will be rejected, even if the token is otherwise valid. This is useful for preventing token sharing or URL redistribution.

To use IP locking, pass the client's IPv4 address as the `userIp` parameter when signing the URL. The IP is included in the HMAC signature but is not appended to the URL itself.
To use IP locking, pass the client's address as the `userIp` parameter when signing the URL. The address is included in the HMAC signature but is not appended to the URL itself.

Both IPv4 and IPv6 addresses are supported, and each family binds at a different prefix length:

| Family | Binds at | Behavior |
| ------ | -------- | -------- |
| IPv4 | `/32` or `/24` | Signing a full address (`203.0.113.42`) binds that exact address. Signing the network address of a `/24` (`203.0.113.0`) accepts any client within that `/24`. |
| IPv6 | `/64` | Only the `/64` prefix is bound, so any address within it is accepted. |

IPv6 always binds at `/64` rather than the full address, because most clients change the rest of their address regularly for privacy. Binding the full address would stop validating as soon as it changed, often within hours, while a client's `/64` stays stable.

For IPv4, you can widen the bind by signing the network address of a `/24` (for example `203.0.113.0` instead of `203.0.113.42`). Tokens signed that way validate for any client within that `/24`, which is useful for clients whose address shifts within a subnet.

<Note>
Only IPv4 addresses are supported. IP locking requires the **Token IP Validation** setting to be enabled on your Pull Zone. Enabling this without including the IP in your tokens will cause all requests to fail. Enabling Token IP Validation also disables IPv6 routing on the Pull Zone to prevent mismatches.
IP locking requires the **Token IP Validation** setting to be enabled on your Pull Zone. Enabling this without including the IP in your tokens will cause all requests to fail.
</Note>

### Address family matching

The signed address must be in the same family the request arrives over. A token signed with an IPv4 address cannot validate a request that arrives over IPv6, nor the reverse.

Enabling **Token IP Validation** therefore pins the Pull Zone to a single family: the zone serves IPv4 only, unless its [IP Family Policy](/cdn/ip-family-policy#token-authentication-and-ip-locking) is set to **IPv6 Only**, which is respected and makes the zone serve IPv6 only. Sign whichever family the zone serves.

<Warning>
IP locking can cause issues for users behind proxies, VPNs, or with frequently changing IP addresses (e.g. mobile networks).
</Warning>
Expand Down Expand Up @@ -81,14 +98,15 @@ Use `token_countries` to allow access only from specific countries, or `token_co
## Generate the token

```
token = "HS256-" + Base64URL(HMAC-SHA256(security_key, signature_path + expires + signing_data + user_ip))
token = "HS256-" + flags + Base64URL(HMAC-SHA256(security_key, signature_path + expires + user_ip + signing_data))
```

Where:
- **`security_key`** is used as the HMAC key (not included in the message)
- **`signature_path`** is the URL path, or the `token_path` override if set
- **`user_ip`** is the optional IP address, omitted entirely when not set. IPv6 addresses are masked to their `/64` prefix before signing
- **`signing_data`** is the alphabetically-sorted parameters joined as `key=value` pairs separated by `&`, excluding `token` and `expires`
- **`user_ip`** is the optional IP address (empty string if not set)
- **`flags`** is `1-` when an IP was signed, and empty otherwise, producing tokens of the form `HS256-1-<hash>`

After Base64 encoding, replace `+` with `-`, `/` with `_`, and remove `=` padding characters.

Expand Down
6 changes: 6 additions & 0 deletions changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ description: "Latest updates and improvements across bunny.net products."
rss: true
---

<Update label="2026-07-31" tags={["CDN","(New)"]}>
## IP Family Policy for Pull Zones

Pull Zones now support an IP Family Policy that controls which address families (IPv4, IPv6, or both) are advertised and which edge servers are eligible to serve the zone. Four policies are available: IPv4 Only, Dual Stack (default), Dual Stack Prefer IPv6, and IPv6 Only. Token authentication IP locking now also supports IPv6 addresses, binding at the client's `/64` prefix. [Learn more](/cdn/ip-family-policy)
</Update>

<Update label="2026-07-16" tags={["Stream","(Improvement)"]}>
## Bunny Player extended Chromecast support

Expand Down
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@
"cdn/pricing",
"cdn/changelog",
"cdn/limits",
"cdn/connectivity"
"cdn/connectivity",
"cdn/ip-family-policy"
]
},
{
Expand Down