DRF pagination “next” link uses a stale hostname behind GKE Ingress — how do I make it use the real host?
What are the details of your problem?
I’m running a Django REST Framework API on Google Kubernetes Engine (GKE) behind an Ingress. When I request:
https://www.my-api-url.com/api/stores/?page=1&active=true
I get correct results, but the pagination next link is built with a stale hostname:
https://api-back.my-api-url.com/api/stores/?active=true&page=2
That hostname used to exist in a previous ingress but was removed. I searched the entire codebase, Kubernetes manifests, and ingress configs and I can’t find it anywhere. I found this related question stating DRF uses the request hostname for the paginator, but I still can’t figure out where that stale host is coming from in a GKE/Ingress setup: How to change the host in next key in a paginated URL in django rest framework?
What did you try and what were you expecting?
I expected DRF to build next with www.my-api-url.com. I checked and/or tried:
ALLOWED_HOSTScontains the correct host.Toggling
USE_X_FORWARDED_HOST(True/False).Setting
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https').Ensuring the new ingress uses the correct public host and removing the old one entirely.
Verified no hard-coded references to
api-back.my-api-url.comin the repo or K8s manifests.Despite that, the
nextlink still shows the stale hostname.Question: In a GKE Ingress setup, which header/setting actually controls the host used by DRF pagination, and how can I ensure
nextuses the real public hostname? If this is coming from a forwarded header, what specific ingress header/config should I set (or unset)?
DRF builds pagination links using request.build_absolute_uri(), which depends on the Host header it receives.
If your app is behind a GKE Ingress or Load Balancer, it’s likely not forwarding the original host —
so Django sees your internal service name like api-back.my-api-url.com.
1. In your Django settings.py:
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
2.In your Ingress annotations, preserve the original host:
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
3.If needed, override DRF’s pagination link generator:
from rest_framework.pagination import PageNumberPagination
class FixedHostPagination(PageNumberPagination):
def get_next_link(self):
url = super().get_next_link()
if url:
return url.replace('api-back.my-api-url.com', 'www.my-api-url.com')
return None
Why it happens:
Your ingress or proxy rewrites the Host header to the internal service name.
DRF uses that to build links, so you end up with stale internal URLs.