Unable to Access Local Services via Domain Name on iPhone

I’m experiencing an issue where I cannot access local services via their domain names on my iPhone while connected to the same WiFi network. The same setup works fine on my laptop. Here’s the context and configuration:


Environment

  • Device: iPhone (iOS 26.1)
  • Browsers Tested: Firefox, Safari, Chrome
  • DNS Server: Pi-hole
  • Traefik Version: 3.6.4

Issue

  • Expected Behavior: Access local services via their domain names (e.g., traefik.example.dev) while connected to the local WiFi.
  • Actual Behavior: Requests are rejected with the following log entry:
    2025-12-16T22:28:55+01:00 DBG ``github.com/traefik/traefik/v3/pkg/middlewares/ipallowlist/ip_allowlist.go:78`` > Rejecting IP x.x.x.x: "x.x.x.x" matched none of the trusted IPs middlewareName=local-whitelist@file middlewareType=IPAllowLister
  • Laptop Behavior: Works as expected on the same WiFi network.

Configuration

Traefik Config (traefik.yml)

global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
  filePath: /var/log/traefik/traefik.log
  format: common
  level: DEBUG
 
api:
  dashboard: true
  insecure: true

entryPoints:
  web:
    address: ':80'
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ':443'
    http:
      tls:
        certResolver: cloudflare
  traefik:
    address: ':8080'
 
serversTransport:
  insecureSkipVerify: true
 
providers:
  file:
    directory: /etc/traefik/conf.d/
    watch: true
 
certificatesResolvers:
  cloudflare:
    acme:
      email: cloudflare@example.com
      storage: /etc/traefik/ssl/acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory
      keyType: EC256
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"
 
accessLog:
  filePath: /var/log/traefik/traefik-access.log
  format: common
  filters:
    statusCodes:
      - "200"
      - "400-599"
    retryAttempts: true
    minDuration: "10ms"
  bufferingSize: 0
  fields:
    headers:
      defaultMode: drop
      names:
        User-Agent: keep

Middleware (middleware.yaml)

http:
  middlewares:
    local-whitelist:
      IPAllowlist:
        sourceRange:
        - "192.168.30.0/24"
        - "192.168.40.0/24"
        - "192.168.50.0/24"
    sslheader:
      headers:
        customRequestHeaders:
          X-Forwarded-Proto: "https"

Routers (routers.yaml)

http:
  routers:
    traefik-route:
      rule: "Host(`traefik.example.dev`)"
      service: traefik-service
      entryPoints:
        - websecure
      middlewares:
        - local-whitelist@file
      tls:
        certResolver: cloudflare
        domains:
          - main: "example.dev"
            sans:
              - "*.example.dev"
 
    traefik-service:
      loadBalancer:
        servers:
          - url: "http://192.168.30.9:8080"

Observations

  • The iPhone’s request is handled with een external IP address (x.x.x.x).
  • Using the local ip address (192.168.30.9:8080) I can access the service web page.
  • The laptop's request is handled with an internal IP address, which works.
  • The iPhone is connected to the same WiFi network as the laptop.
  • I have disabled all privacy settings on my phone, Privacy wifi-address, Restrict IP-address tacking, Safari > Hide IP Address, Prevent Cross-Site Tracking, etc

What could be the issue?

Enable Traefik debug log (doc) and Traefik access log in JSON format (doc).

Access log should show you the source IP address, so you can check if it matches allowed ones.

What IP is traefik.example.dev pointing to? Is it different for external and internal? Can you check logs of PiHole if iPhone uses it?