308 - Permanent Redirect
HTTP 308 Permanent Redirect means resource moved permanently and redirect must preserve request method and body.
Last reviewed: February 12, 2026|Editorial standard: source-backed technical guidance
What Does Permanent Redirect Mean?
The resource has permanently moved, and clients must preserve original method and body while switching to the new canonical URI.
Common Causes
- -Endpoint permanently migrated while preserving method semantics.
- -Canonical host or path policy enforces permanent method-safe redirect.
- -API base path changed but operation semantics remain identical.
How to Fix Permanent Redirect
- 1Validate permanent redirect targets and ensure destination endpoints support original method and body.
- 2Migrate clients, SDK base URLs, and internal links to the canonical URI to reduce redirect overhead.
- 3Align cache, canonical, and edge routing policy so 308 remains single-hop and stable across regions.
Step-by-Step Diagnosis for Permanent Redirect
- 1Capture request method/URI and `Location` mapping for all 308-emitting routes.
- 2Verify clients preserve method/body semantics when following permanent redirects.
- 3Inspect canonicalization rules for host/scheme/path conflicts or permanent loop risks.
- 4Retest migration paths for both read and write methods across all supported clients.
Permanent Mapping and Canonical Policy Audit
- -Validate one-hop permanent map (example: old API path permanently maps to new path without intermediate 301/302 chain).
- -Check for canonical policy conflicts (example: host canonicalization plus path migration creates cyclic 308 chain).
Method-Preserving Client Compatibility Checks
- -Test write methods through redirect path (example: PUT request body dropped by legacy HTTP client on 308).
- -Audit SDK/runtime redirect defaults (example: library follows 308 but strips custom auth headers on destination host).
Implementation Examples
curl -i -X PUT https://api.example.com/v1/resource -H "Content-Type: application/json" -d "{"name":"v2"}"
# Response:
# HTTP/1.1 308 Permanent Redirect
# Location: https://api.example.com/v2/resourceconst response = await fetch('https://api.example.com/v1/resource', {
method: 'PUT',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'v2' }),
redirect: 'manual'
});
if (response.status === 308) {
console.error('Handle 308 Permanent Redirect:', response.headers.get('location'));
}import requests
response = requests.put(
'https://api.example.com/v1/resource',
headers={'Accept': 'application/json', 'Content-Type': 'application/json'},
json={'name': 'v2'},
allow_redirects=False
)
if response.status_code == 308:
print('Handle 308 Permanent Redirect', response.headers.get('Location'))How to Verify the Fix
- -Confirm old URIs return one 308 hop and operations succeed at the destination without method changes.
- -Validate client traffic progressively shifts to canonical URIs and redirect load declines over time.
- -Check for zero method or body loss regressions in write-path telemetry after 308 migration rollout.
How to Prevent Recurrence
- -Plan permanent URI migrations with compatibility windows, telemetry checkpoints, and rollback criteria.
- -Publish 308 behavior requirements in API docs and verify SDK support before deprecating old endpoints.
- -Continuously audit canonical routing and cache policies for drift across CDN and origin infrastructure.
Pro Tip
- -pair every 308 rollout with client telemetry gating so deprecation proceeds only after high-risk SDK versions are below threshold.
Decision Support
Compare Guide
403 Forbidden vs 404 Not Found: When to Hide Resources
Use 403 for explicit access denial, or 404 to conceal resource existence when security policy requires reducing endpoint and object enumeration risk.
Compare Guide
404 Not Found vs 410 Gone: Missing vs Permanent Removal
Learn when to return 404 (missing or temporary absence) versus 410 (intentional permanent removal), including redirect and cache implications.
Playbook
Resource State Playbook (404 / 410 / ResourceNotFound)
Use this playbook to separate temporary missing-resource lookups from permanent removals, then fix scope, lifecycle, and identifier drift safely.
Official References
Provider Context
This guidance is specific to HTTP services. Always validate implementation details against official provider documentation before deploying to production.