Fixing Licensing When Your Server Sends 127.0.0.1, localhost, or ::1 Print

  • 0

Problem

If your license check is sending 127.0.0.1, localhost, ::1, or another loopback/internal address instead of your real server IP, the licensing server may reject the request because it does not match the licensed machine.

This usually happens when:

  • PHP is running behind a reverse proxy.
  • Apache is listening on 127.0.0.1:8080 behind NGINX.
  • OpenLiteSpeed or LiteSpeed is passing a local backend IP into PHP.
  • A control panel such as aaPanel, Plesk, cPanel, or DirectAdmin is using a proxy stack.
  • The server only exposes loopback/local interface values to PHP.
  • An old detected IP is cached locally.

What Cockpit Uses for Licensing IP

Cockpit checks the server IP in this order:

  1. $_SERVER['SERVER_ADDR']
  2. $_SERVER['LOCAL_ADDR']
  3. Cached detected public IPv4
  4. Public IPv4 discovered from remote lookup
  5. IPv4 resolved from the panel domain
  6. Last fallback server address

If your stack feeds PHP 127.0.0.1, ::1, or localhost, licensing can fail unless the real public IPv4 is passed into PHP correctly.

Important Rule

For licensing, you want PHP to expose the server's real public IPv4 address.

Do not use:

  • 127.0.0.1
  • ::1
  • localhost
  • Docker bridge IPs
  • LAN/private IPs such as 10.x.x.x, 172.16-31.x.x, 192.168.x.x
  • Cloudflare visitor IP headers like CF-Connecting-IP

Cloudflare headers represent the visitor IP, not your server IP.

Quick Test

Create a temporary file named server-ip-test.php inside your panel root with this content:

<?php
header('Content-Type: text/plain');
echo 'SERVER_ADDR=' . ($_SERVER['SERVER_ADDR'] ?? '') . PHP_EOL;
echo 'LOCAL_ADDR=' . ($_SERVER['LOCAL_ADDR'] ?? '') . PHP_EOL;
echo 'SERVER_NAME=' . ($_SERVER['SERVER_NAME'] ?? '') . PHP_EOL;
echo 'HTTP_HOST=' . ($_SERVER['HTTP_HOST'] ?? '') . PHP_EOL;

Open it in your browser.

If SERVER_ADDR or LOCAL_ADDR shows 127.0.0.1, ::1, localhost, or a private IP, your web stack needs adjusting.

Delete this file after testing.

After You Fix the Web Server Config

Clear the cached IP so Cockpit re-detects the correct address.

Delete these files if they exist:

  • includes/db/cockpit_license.local.lic.ip4
  • includes/db/cockpit_license.local.lic

The first file clears the cached detected IPv4. The second forces a fresh remote license check.

If you only remove one file, remove .ip4 first.

NGINX + PHP-FPM

If you run NGINX directly with PHP-FPM, explicitly pass the server IP into PHP.

Add this inside your PHP location block:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param SERVER_ADDR $server_addr;
    fastcgi_param LOCAL_ADDR $server_addr;
}

If $server_addr still resolves to the wrong address in your setup, replace it with the real public IPv4 directly:

fastcgi_param SERVER_ADDR 203.0.113.10;
fastcgi_param LOCAL_ADDR 203.0.113.10;

Then reload NGINX and PHP-FPM:

sudo systemctl reload nginx
sudo systemctl reload php8.2-fpm

Use your installed PHP-FPM version if it is different.

NGINX Reverse Proxy in Front of Apache

This is one of the most common reasons 127.0.0.1 appears.

Example stack:

  • NGINX listens on public ports 80/443
  • Apache listens internally on 127.0.0.1:8080
  • PHP runs through Apache

In this layout, Apache may expose loopback as the server address unless you override it.

Option A: Pass the public IP into Apache as an environment value

If Apache is serving PHP, define the public IP inside the Apache vhost.

<VirtualHost *:8080>
    ServerName panel.example.com
    DocumentRoot /var/www/html

    SetEnv SERVER_ADDR 203.0.113.10
    SetEnv LOCAL_ADDR 203.0.113.10
</VirtualHost>

Option B: If Apache uses PHP-FPM via proxy_fcgi

Use:

<VirtualHost *:8080>
    ServerName panel.example.com
    DocumentRoot /var/www/html

    ProxyFCGISetEnvIf "true" SERVER_ADDR "203.0.113.10"
    ProxyFCGISetEnvIf "true" LOCAL_ADDR "203.0.113.10"
</VirtualHost>

Restart Apache after saving.

Apache with mod_php

If you are using Apache directly with mod_php, add this to the correct vhost:

<VirtualHost *:80>
    ServerName panel.example.com
    DocumentRoot /var/www/html

    SetEnv SERVER_ADDR 203.0.113.10
    SetEnv LOCAL_ADDR 203.0.113.10
</VirtualHost>

If HTTPS is enabled, repeat it in the SSL vhost too.

Then restart Apache:

sudo systemctl restart apache2

On RHEL, AlmaLinux, Rocky Linux, or CentOS:

sudo systemctl restart httpd

Apache with PHP-FPM

If Apache uses PHP-FPM instead of mod_php, add these lines inside the vhost:

ProxyFCGISetEnvIf "true" SERVER_ADDR "203.0.113.10"
ProxyFCGISetEnvIf "true" LOCAL_ADDR "203.0.113.10"

Full example:

<VirtualHost *:443>
    ServerName panel.example.com
    DocumentRoot /var/www/html

    ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php/php8.2-fpm.sock|fcgi://localhost/var/www/html/

    ProxyFCGISetEnvIf "true" SERVER_ADDR "203.0.113.10"
    ProxyFCGISetEnvIf "true" LOCAL_ADDR "203.0.113.10"
</VirtualHost>

Then restart Apache and PHP-FPM.

OpenLiteSpeed

OpenLiteSpeed often sits behind a panel-generated configuration, and depending on the setup, PHP may see a local address instead of the public server IP.

You need to expose the public IP as environment variables for the vhost handling Cockpit.

Option A: Virtual Host Environment

In OpenLiteSpeed WebAdmin:

  1. Open Virtual Hosts
  2. Open the vhost for your Cockpit domain
  3. Go to General
  4. Add environment variables for the vhost

Set:

SERVER_ADDR=203.0.113.10
LOCAL_ADDR=203.0.113.10

Option B: Rewrite Environment Variables

If you manage the vhost config manually, use rewrite environment flags:

RewriteEngine On
RewriteRule .* - [E=SERVER_ADDR:203.0.113.10,E=LOCAL_ADDR:203.0.113.10]

Then perform a graceful restart of OpenLiteSpeed.

LiteSpeed Enterprise

For LiteSpeed Enterprise, the fix is the same idea: ensure the PHP environment receives the public server IP, not loopback.

Use one of these methods depending on how your vhost is built:

  • Add environment variables in the vhost config
  • Add rewrite environment variables
  • If running behind a local reverse proxy, bypass the local-only address and set the public IP explicitly

Example rewrite-based override:

RewriteEngine On
RewriteRule .* - [E=SERVER_ADDR:203.0.113.10,E=LOCAL_ADDR:203.0.113.10]

If your host manages LiteSpeed for you, send support the exact ticket text shown later in this guide.

aaPanel

aaPanel can run sites on NGINX, Apache, or OpenLiteSpeed. The fix depends on which engine your site uses.

aaPanel with NGINX

Open the site config in aaPanel and add this to the PHP location block:

fastcgi_param SERVER_ADDR 203.0.113.10;
fastcgi_param LOCAL_ADDR 203.0.113.10;

Then reload NGINX and PHP-FPM.

aaPanel with Apache

Open the site vhost config and add:

SetEnv SERVER_ADDR 203.0.113.10
SetEnv LOCAL_ADDR 203.0.113.10

Or if using PHP-FPM through Apache:

ProxyFCGISetEnvIf "true" SERVER_ADDR "203.0.113.10"
ProxyFCGISetEnvIf "true" LOCAL_ADDR "203.0.113.10"

Then restart Apache.

aaPanel with OpenLiteSpeed

Add these environment overrides in the site or vhost config:

SERVER_ADDR=203.0.113.10
LOCAL_ADDR=203.0.113.10

Or use the rewrite environment override shown in the OpenLiteSpeed section.

cPanel and WHM

Shared Hosting

On shared hosting, you usually cannot change Apache or LiteSpeed internals yourself.

Your host must expose the real public server IP to PHP.

Send this to support:

My PHP environment is exposing SERVER_ADDR / LOCAL_ADDR as 127.0.0.1, ::1, localhost, or another internal IP. My licensing system requires the real public server IPv4. Please configure the vhost/PHP handler for this account so PHP receives the server's public IPv4 in SERVER_ADDR and LOCAL_ADDR instead of loopback or proxy-local values.

VPS or Dedicated Server with WHM

If you control WHM and Apache or LiteSpeed yourself, add the Apache or LiteSpeed override from the sections above.

If Apache is behind NGINX or another reverse proxy, set the public IP explicitly instead of trusting loopback.

Plesk

In Plesk, add custom Apache or NGINX directives depending on your stack.

Apache directives

SetEnv SERVER_ADDR 203.0.113.10
SetEnv LOCAL_ADDR 203.0.113.10

Apache + PHP-FPM

ProxyFCGISetEnvIf "true" SERVER_ADDR "203.0.113.10"
ProxyFCGISetEnvIf "true" LOCAL_ADDR "203.0.113.10"

NGINX directives

fastcgi_param SERVER_ADDR 203.0.113.10;
fastcgi_param LOCAL_ADDR 203.0.113.10;

Apply the config and reload the web service stack.

DirectAdmin

For DirectAdmin, the fix depends on whether the site is using Apache, NGINX, or OpenLiteSpeed.

Use the matching section from this guide.

If CustomBuild is generating your configs, make sure your custom templates preserve:

  • SetEnv SERVER_ADDR ... for Apache
  • ProxyFCGISetEnvIf ... for Apache + PHP-FPM
  • fastcgi_param SERVER_ADDR ... for NGINX
  • environment overrides for OpenLiteSpeed

Shared Hosting Users

If you are on shared hosting, the most important point is this:

You usually cannot fix this fully inside Cockpit.

The hosting provider must change the site stack so PHP sees the real public server IPv4.

What to ask your host

Send this exact message:

My PHP application licensing needs PHP to expose the real public server IPv4 in SERVER_ADDR or LOCAL_ADDR. Right now PHP is reporting 127.0.0.1, localhost, ::1, or another internal address. Please update the vhost / reverse proxy / PHP handler configuration for my domain so SERVER_ADDR and LOCAL_ADDR return the public server IPv4 instead of loopback or internal proxy values.

If the host asks why, tell them:

The licensing server validates the machine IP and rejects loopback or internal-only values. This is a server configuration issue, not an application bug.

VPS Users

If you run your own VPS, you normally can fix this yourself.

Check these first

  • Is NGINX proxying to Apache on 127.0.0.1?
  • Is Apache only listening on loopback?
  • Is OpenLiteSpeed passing local values into PHP?
  • Is PHP-FPM missing SERVER_ADDR and LOCAL_ADDR overrides?
  • Is the public IPv4 assigned to the vhost/interface you expect?

Best practice on VPS

Set the public server IPv4 explicitly in the site config instead of hoping $server_addr resolves correctly in a proxied stack.

Dedicated Server Users

Dedicated servers follow the same fix as VPS, but you should also check:

  • multiple NICs or bonded interfaces
  • public IP on a different interface than the web service listener
  • NAT, firewall, or hardware load balancer in front of the web service
  • reverse proxy software such as NGINX Proxy Manager or HAProxy

If your app is behind a local proxy, the backend may only see 127.0.0.1 unless you override the PHP environment values manually.

Docker, Containers, and Proxy Managers

If Cockpit runs inside Docker, LXC, or behind a proxy manager:

  • the container IP is not the licensed public IP
  • the reverse proxy address is not the licensed public IP
  • you should pass the host's public IPv4 into the PHP environment explicitly

For NGINX-based containers, use:

fastcgi_param SERVER_ADDR 203.0.113.10;
fastcgi_param LOCAL_ADDR 203.0.113.10;

For Apache-based containers, use:

SetEnv SERVER_ADDR 203.0.113.10
SetEnv LOCAL_ADDR 203.0.113.10

IPv6 Note

Cockpit licensing currently prefers a public IPv4.

If your server only exposes IPv6 and no public IPv4, configure the public IPv4 that your license is tied to, or make sure your domain resolves to a public IPv4 that matches the licensed machine.

Final Checklist

  1. Make sure PHP no longer reports 127.0.0.1, localhost, or ::1 for SERVER_ADDR or LOCAL_ADDR.
  2. Confirm the value is your real public server IPv4.
  3. Remove includes/db/cockpit_license.local.lic.ip4.
  4. If needed, remove includes/db/cockpit_license.local.lic.
  5. Re-test the panel and force a fresh license check.

If It Still Fails

  • verify the public IPv4 is the same one registered in licensing
  • verify the domain resolves to the correct public IPv4
  • verify you are not passing visitor IP headers into the license check
  • verify your reverse proxy is not rewriting the PHP environment again after your change
  • verify the old cached IP file was removed

Was this answer helpful?

« Back