I recently needed to migrate over 40 subdomain redirects from my domain registrar's web forwarding service to Cloudflare. What seemed like a straightforward task turned into an educational journey through Cloudflare's API limitations and redirect systems. Here's what I learned.
The Goal
Replace my registrar's web forwarding rules with Cloudflare-managed redirects for 40+ subdomains across multiple domains (a6n.co.uk, this testing was done with pokebearswithsticks.com). Each subdomain needed to redirect to various destinations - some to Azure static sites, others to external services.
Example redirects:
legal.a6n.co.uk→https://bloguk2.z13.web.core.windows.net/legal.htmlservice.a6n.co.uk→https://a6n.statuspage.io/support.a6n.co.uk→ Google Forms URL
Visual End Result
This shows the zones all added to Cloudflare with the "proxy" icon to confirm those records are being proxied:
Then we have the bulk redirection options which you can find under Rules>Settings as below:
First you need the set the "Bulk Redirect Lists" which will be inactive, as you can see they are active here:
Those lists are active because they are linked to a Bulk Redirect Rule that is enabled:
If we look at the a6n.co.uk rule you can see that the rule links to the list as below:
Initial Approach: Single Redirects
My first instinct was to use Cloudflare's new Single Redirects feature, which replaced the deprecated Page Rules. I wrote a PowerShell script to batch-add all redirects via the API:
foreach ($redirect in $redirects) {
$rule = @{
action = "redirect"
action_parameters = @{
from_value = @{
status_code = $redirect.status
target_url = @{
value = $redirect.destination
}
preserve_query_string = $false
}
}
expression = "(http.host eq `"$($redirect.subdomain).a6n.co.uk`")"
description = "Redirect $($redirect.subdomain).a6n.co.uk"
enabled = $true
}
$rules += $rule
}
Lesson 1: Know Your Limits
The script failed immediately with a clear error message:
{
"errors": [{
"code": 50001,
"message": "exceeded the maximum number of rules in the phase http_request_dynamic_redirect: 40 out of 10"
}]
}
Key Learning: Cloudflare's free plan limits Single Redirects to just 10 rules. This wasn't immediately obvious from the dashboard, which happily let me start creating rules without warning about the limit.
Pivot to Bulk Redirects
After discovering the 10-rule limit, I learned about Bulk Redirects - a different system that handles unlimited redirects on all plans. However, this required a complete rewrite since Bulk Redirects work differently:
- Create a list of redirect mappings
- Add items to the list
- Create a rule to activate the list
Lesson 2: API Authentication Methods Matter
When trying to update existing rulesets, I hit another roadblock:
{
"errors": [{
"code": 10000,
"message": "PATCH method not allowed for the api_token authentication scheme"
}]
}
Key Learning: Not all HTTP methods are available with API token authentication. I had to use PUT with complete payloads instead of PATCH for partial updates:
# Wrong - PATCH not allowed with API tokens
$response = Invoke-RestMethod -Uri $updateUrl -Method Patch -Headers $headers -Body $updateBody
# Correct - PUT with complete ruleset
$updateBody = @{
description = $currentRuleset.result.description
kind = "root"
phase = "http_request_redirect"
rules = $updatedRules
} | ConvertTo-Json -Depth 10
$response = Invoke-RestMethod -Uri $updateUrl -Method Put -Headers $headers -Body $updateBody
Lesson 3: Naming Conventions Are Strict
Creating the Bulk Redirect list failed with an unhelpful error:
{
"errors": [{
"code": 10029,
"message": "invalid_name"
}]
}
Key Learning: Cloudflare list names must use only alphanumeric characters and underscores. No hyphens allowed:
# Wrong
$listName = "a6n-redirects-20241228"
# Correct
$listName = "a6n_redirects_20241228"
Lesson 4: API Permissions Are Nuanced
The permissions required for different operations aren't always what you'd expect:
- Single Redirects: Requires "Zone > Single Redirect > Edit"
- Bulk Redirects: Requires "Account > Account Filter Lists > Edit" and "Account > Account Rulesets > Edit"
Note that Bulk Redirects operate at the account level, not zone level, which is why they need different permissions.
The Complete Solution
Here's the working approach for Bulk Redirects:
# Step 1: Create DNS records (required for redirects to work)
foreach ($subdomain in $subdomains) {
$body = @{
type = "A"
name = $subdomain
content = "192.0.2.1" # Dummy IP - never reached due to redirect
ttl = 1
proxied = $true # Must be proxied for redirects to work
} | ConvertTo-Json
}
# Step 2: Create Bulk Redirect list
$listName = "a6n_redirects_$(Get-Date -Format 'yyyyMMddHHmmss')"
$createListBody = @{
name = $listName
description = "Redirect list for a6n.co.uk subdomains"
kind = "redirect"
} | ConvertTo-Json
# Step 3: Add redirect items
$items = @()
foreach ($redirect in $redirects) {
$items += @{
redirect = @{
source_url = "https://$($redirect.source)/"
target_url = $redirect.target
status_code = $redirect.status
preserve_query_string = $false
include_subdomains = $false
subpath_matching = $false
preserve_path_suffix = $false
}
}
}
# Step 4: Create rule to activate the list
$bulkRule = @{
action = "redirect"
action_parameters = @{
from_list = @{
name = $listName
key = "http.request.full_uri"
}
}
expression = "http.request.full_uri in `$" + $listName
description = "Bulk redirects for a6n.co.uk"
enabled = $true
}
Lesson 5: DNS Records Are Essential
One crucial detail that's easy to miss: redirects only work if DNS records exist and are proxied through Cloudflare. Each subdomain needs an A record pointing to a dummy IP (192.0.2.1) with the proxy enabled (orange cloud). Without this, Cloudflare never sees the traffic to redirect it.
Conclusions
- Check limits before implementation - Single Redirects seem perfect until you hit the 10-rule limit
- Understand the API authentication model - Not all HTTP methods work with API tokens
- Pay attention to naming conventions - "invalid_name" errors could be more descriptive
- Account vs Zone permissions - Different Cloudflare features operate at different levels
- Don't forget the DNS - Redirects need proxied DNS records to function
The complete PowerShell scripts are available if you need to do a similar migration. While the journey had its frustrations, Bulk Redirects proved to be a powerful solution that actually exceeded my original requirements by removing the redirect limit entirely.