Skip to content

Access List clients are sometimes created in the wrong order #5405

@edklesel

Description

@edklesel

Checklist

  • Have you pulled and found the error with jc21/nginx-proxy-manager:latest docker image?
    • Yes
  • Are you sure you're not using someone else's docker image?
    • Yes
 % date && docker ps | grep -P 'npm$'
Sun 15 Mar 09:48:51 GMT 2026
1a9afd22111b   jc21/nginx-proxy-manager:latest   "/init"                  4 minutes ago   Up 4 minutes (healthy)   80/tcp, 443/tcp, 0.0.0.0:81->81/tcp, :::81->81/tcp          npm
  • Have you searched for similar issues (both open and closed)?
    • Yes

Describe the bug
When creating access lists with clients, very occasionally the clients will be created in a different order to what was specified in the API request.

I have a feeling this is due to the async functionality in backend/internal/access-list.js, as the clients may be inserted asynchronously into the database and so there's a chance they go in the wrong order. However, I'm not a developer and not overly familiar with JS, so it's just a hunch.

Nginx Proxy Manager Version
2.14.0

To Reproduce
This script can be run to reproduce it, with the following assumptions:

  • jq is installed
  • Nginx Proxy Manager is running on localhost port 81 with the (old) default credentials
NPM_HOST="http://localhost:81"
NPM_USERNAME="admin@example.com"
NPM_PASSWORD="changeme"

AUTH="
{
    \"identity\":\"${NPM_USERNAME}\",
    \"secret\":\"${NPM_PASSWORD}\"
}
"
TOKEN=$(curl -s -X POST "${NPM_HOST}/api/tokens" --data "$AUTH" -H 'Content-Type: application/json' | jq -r '.token')

ACCESS_LIST_JSON='
{
    "name": "test",
    "clients": [
        {
            "address": "1.2.3.4",
            "directive": "deny"
        },
        {
            "address": "2.3.4.5",
            "directive": "allow"
        },
        {
            "address": "3.4.5.6",
            "directive": "deny"
        }
    ],
    "items": []
}
'

while true;
do
    ACCESS_LIST=$(curl -s -X POST "${NPM_HOST}/api/nginx/access-lists" -H 'Content-Type: application/json' -H "Authorization: Bearer ${TOKEN}" --data "${ACCESS_LIST_JSON}")

    ADDRESS_0=$(echo $ACCESS_LIST | jq -r '.clients[0].address')

    if [ $ADDRESS_0 != "1.2.3.4" ]; then echo $ADDRESS_0; echo $ACCESS_LIST | jq '.clients[]'; break; fi
    date
    sleep 0.1
done

This script will create 10 access lists per second (actually fewer due to API response times), and will break and output when the address of the first client isn't "1.2.3.4", which is what was specified in the creation request. The script will print the clients for the created access list, showing that they are in the wrong order.

Expected behavior
When creating an access list, the following is specified:

Note that the allow and deny directives will be applied in the order they are defined.

Therefore, the order should be preserved during creation, and if there is a mistake in the order then that could affect the behaviour of the access list.

Screenshots
Example from when I ran the script just before creating the issue.

Image

Operating System
Docker Compose running on Ubuntu 24.04.4

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions