[GH-ISSUE #3834] Unable to add peers with user login on self-hosted with Entra ID #7965

Open
opened 2026-08-05 01:15:25 -04:00 by saavagebueno · 0 comments
Owner

Originally created by @mrll on GitHub (May 16, 2025).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/3834

Describe the problem

I have setup a new netbird server, following the advanced guide. So far everything works, but I am not able to connect client using the user login. Setup keys work. I'm using Entra ID as the IdP and have Caddy as reverse proxy.

To Reproduce

Steps to reproduce the behavior:

  1. Open netbird client
  2. Click on 'Connect'
  3. Login with Entra ID
  4. See error

Expected behavior

Peers to be added and connected with user login.

Are you using NetBird Cloud?

Self-hosted

NetBird version

0.43.3

Is any other VPN software installed?

No

Debug output

netbird status -dA

Daemon status: LoginFailed

Run UP command to log in with SSO (interactive login):

 netbird up

If you are running a self-hosted version and no SSO provider has been configured in your Management Server,
you can use a setup-key:

 netbird up --management-url <YOUR_MANAGEMENT_URL> --setup-key <YOUR_SETUP_KEY>

More info: https://docs.netbird.io/how-to/register-machines-using-setup-keys

netbird debug for 1m -AS

Error: failed to up: up already in progress: current status LoginFailed

Screenshots

When using netbird up I get the following output:

netbird up
Please do the SSO login in your browser.
If your browser didn't open automatically, use this URL to log in:

https://login.microsoftonline.com/...

Error: waiting sso login failed with: rpc error: code = Unknown desc = validate access token failed with error: invalid JWT token audience field

But the browser shows:

Image

On the management logs I get this error:

management-1  | 2025-05-16T07:24:30Z WARN [peerID: ..., context: GRPC, requestID: ..., accountID: UNKNOWN] management/server/grpcserver.go:474: failed logging in peer ...: no peer auth method provided, please use a setup key or interactive SSO login

I also tried this on different devices with the same issue. Mobile devices like iOS get stuck on connecting.

Additional context

My docker compose file:

services:
  # Caddy reverse proxy
  caddy:
    image: caddy
    restart: unless-stopped
    networks: [ netbird ]
    ports:
      - '443:443'
      - '443:443/udp'
      - '80:80'
    volumes:
      - netbird_caddy_data:/data
      - ./Caddyfile:/etc/caddy/Caddyfile
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # UI dashboard
  dashboard:
    image: netbirdio/dashboard:latest
    restart: unless-stopped
    networks: [ netbird ]
    env_file:
      - ./dashboard.env
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # Signal
  signal:
    image: netbirdio/signal:latest
    restart: unless-stopped
    networks: [ netbird ]
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # Relay
  relay:
    image: netbirdio/relay:latest
    restart: unless-stopped
    networks: [netbird ]
    env_file:
      - ./relay.env
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # Management
  management:
    image: netbirdio/management:latest
    restart: unless-stopped
    networks: [ netbird ]
    depends_on:
      - dashboard
    volumes:
      - netbird_management:/var/lib/netbird
      - ./management.json:/etc/netbird/management.json
    command: [
      "--port", "80",
      "--log-file", "console",
      "--log-level", "debug",
      "--disable-anonymous-metrics=false",
      "--single-account-mode-domain=net.REDACTED",
      "--dns-domain=net.REDACTED",
      "--idp-sign-key-refresh-enabled",
      ]
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # Coturn
  coturn:
    image: coturn/coturn:latest
    restart: unless-stopped
    domainname: REDACTED
    volumes:
      - ./turnserver.conf:/etc/turnserver.conf:ro
    network_mode: host
    command:
      - -c /etc/turnserver.conf
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

volumes:
  netbird_management:
  netbird_caddy_data:

networks:
  netbird:

The dashboard env:

# Endpoints
NETBIRD_MGMT_API_ENDPOINT=https://REDACTED:443
NETBIRD_MGMT_GRPC_API_ENDPOINT=https://REDACTED:443

# OIDC
AUTH_AUDIENCE=REDACTED-AppID
AUTH_CLIENT_ID=REDACTED-AppID

AUTH_AUTHORITY=https://login.microsoftonline.com/REDACTED-TenantID/v2.0
USE_AUTH0=false
AUTH_SUPPORTED_SCOPES=openid profile email offline_access User.Read api://REDACTED-AppID/api
AUTH_REDIRECT_URI=/auth
AUTH_SILENT_REDIRECT_URI=/silent-auth
NETBIRD_TOKEN_SOURCE=idToken

# SSL
NGINX_SSL_PORT=443

# Letsencrypt
LETSENCRYPT_DOMAIN=none

Caddyfile

{
  debug
    servers :80,:443 {
      protocols h1 h2c
  }
}

(security_headers) {
    header * {
        # enable HSTS
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#strict-transport-security-hsts
        # NOTE: Read carefully how this header works before using it.
        # If the HSTS header is misconfigured or if there is a problem with
        # the SSL/TLS certificate being used, legitimate users might be unable
        # to access the website. For example, if the HSTS header is set to a
        # very long duration and the SSL/TLS certificate expires or is revoked,
        # legitimate users might be unable to access the website until
        # the HSTS header duration has expired.
        # The recommended value for the max-age is 2 year (63072000 seconds).
        # But we are using 1 hour (3600 seconds) for testing purposes
        # and ensure that the website is working properly before setting
        # to two years.

        Strict-Transport-Security "max-age=3600; includeSubDomains; preload"

        # disable clients from sniffing the media type
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-content-type-options
        X-Content-Type-Options "nosniff"

        # clickjacking protection
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-frame-options
        X-Frame-Options "SAMEORIGIN"

        # xss protection
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-xss-protection
        X-XSS-Protection "1; mode=block"

        # Remove -Server header, which is an information leak
        # Remove Caddy from Headers
        -Server

        # keep referrer data off of HTTP connections
        # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#referrer-policy
        Referrer-Policy strict-origin-when-cross-origin
    }
}

:80, REDACTED:443 {
    import security_headers
    # relay
    reverse_proxy /relay* relay:80
    # Signal
    reverse_proxy /signalexchange.SignalExchange/* h2c://signal:10000
    # Management
    reverse_proxy /api/* management:80
    reverse_proxy /management.ManagementService/* h2c://management:80
    # Dashboard
    reverse_proxy /* dashboard:80
}

management.json

{
    "Stuns": [
        {
            "Proto": "udp",
            "URI": "stun:REDACTED:3478",
            "Username": "",
            "Password": ""
        }
    ],
    "TURNConfig": {
        "TimeBasedCredentials": false,
        "CredentialsTTL": "12h0m0s",
        "Secret": "secret",
        "Turns": [
            {
                "Proto": "udp",
                "URI": "turn:REDACTED:3478",
                "Username": "self",
                "Password": "REDACTED"
            }
        ]
    },
    "Relay": {
        "Addresses": [
            "rel://REDACTED:443"
        ],
        "CredentialsTTL": "24h0m0s",
        "Secret": "REDACTED"
    },
    "Signal": {
        "Proto": "https",
        "URI": "REDACTED:443",
        "Username": "",
        "Password": ""
    },
    "Datadir": "/var/lib/netbird/",
    "DataStoreEncryptionKey": "REDACTED",
    "HttpConfig": {
        "LetsEncryptDomain": "",
        "CertFile": "",
        "CertKey": "",
        "AuthAudience": "REDACTED-AppID",
        "AuthIssuer": "https://login.microsoftonline.com/REDACTED-TenantID/v2.0",
        "AuthUserIDClaim": "oid",
        "AuthKeysLocation": "https://login.microsoftonline.com/REDACTED-TenantID/discovery/v2.0/keys",
        "OIDCConfigEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/v2.0/.well-known/openid-configuration",
        "IdpSignKeyRefreshEnabled": false,
        "ExtraAuthAudience": ""
    },
    "IdpManagerConfig": {
        "ManagerType": "azure",
        "ClientConfig": {
            "Issuer": "https://login.microsoftonline.com/REDACTED-TenantID/v2.0",
            "TokenEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/token",
            "ClientID": "REDACTED-AppID",
            "ClientSecret": "REDACTED-AppSecret",
            "GrantType": "client_credentials"
        },
        "ExtraConfig": {
            "GraphApiEndpoint": "https://graph.microsoft.com/v1.0",
            "ObjectId": "REDACTED-ObjectID"
        },
        "Auth0ClientCredentials": null,
        "AzureClientCredentials": null,
        "KeycloakClientCredentials": null,
        "ZitadelClientCredentials": null
    },
    "DeviceAuthorizationFlow": {
        "Provider": "none",
        "ProviderConfig": {
            "ClientID": "",
            "ClientSecret": "",
            "Domain": "",
            "Audience": "REDACTED-AppID",
            "TokenEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/token",
            "DeviceAuthEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/devicecode",
            "AuthorizationEndpoint": "",
            "Scope": "openid",
            "UseIDToken": false,
            "RedirectURLs": null,
            "DisablePromptLogin": false
        }
    },
    "PKCEAuthorizationFlow": {
        "ProviderConfig": {
            "ClientID": "REDACTED-AppID",
            "ClientSecret": "",
            "Domain": "",
            "Audience": "REDACTED-AppID",
            "TokenEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/token",
            "DeviceAuthEndpoint": "",
            "AuthorizationEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/authorize",
            "Scope": "openid profile email offline_access User.Read api://REDACTED-AppID/api",
            "UseIDToken": false,
            "RedirectURLs": [
                "http://localhost:53000"
            ],
            "DisablePromptLogin": false
        }
    },
    "StoreConfig": {
        "Engine": "sqlite"
    },
    "ReverseProxy": {
        "TrustedHTTPProxies": [],
        "TrustedHTTPProxiesCount": 0,
        "TrustedPeers": [
            "0.0.0.0/0"
        ]
    }
}

Have you tried these troubleshooting steps?

  • Checked for newer NetBird versions
  • Searched for similar issues on GitHub (including closed ones)
  • Restarted the NetBird client
  • Disabled other VPN software
  • Checked firewall settings
Originally created by @mrll on GitHub (May 16, 2025). Original GitHub issue: https://github.com/netbirdio/netbird/issues/3834 **Describe the problem** I have setup a new netbird server, following the advanced guide. So far everything works, but I am not able to connect client using the user login. Setup keys work. I'm using Entra ID as the IdP and have Caddy as reverse proxy. **To Reproduce** Steps to reproduce the behavior: 1. Open netbird client 2. Click on 'Connect' 3. Login with Entra ID 4. See error **Expected behavior** Peers to be added and connected with user login. **Are you using NetBird Cloud?** Self-hosted **NetBird version** `0.43.3` **Is any other VPN software installed?** No **Debug output** netbird status -dA ``` Daemon status: LoginFailed Run UP command to log in with SSO (interactive login): netbird up If you are running a self-hosted version and no SSO provider has been configured in your Management Server, you can use a setup-key: netbird up --management-url <YOUR_MANAGEMENT_URL> --setup-key <YOUR_SETUP_KEY> More info: https://docs.netbird.io/how-to/register-machines-using-setup-keys ``` netbird debug for 1m -AS ``` Error: failed to up: up already in progress: current status LoginFailed ``` **Screenshots** When using netbird up I get the following output: ``` netbird up Please do the SSO login in your browser. If your browser didn't open automatically, use this URL to log in: https://login.microsoftonline.com/... Error: waiting sso login failed with: rpc error: code = Unknown desc = validate access token failed with error: invalid JWT token audience field ``` But the browser shows: ![Image](https://github.com/user-attachments/assets/5ccda25b-69c5-4dd8-9c9a-d35358cc6ba7) On the management logs I get this error: ``` management-1 | 2025-05-16T07:24:30Z WARN [peerID: ..., context: GRPC, requestID: ..., accountID: UNKNOWN] management/server/grpcserver.go:474: failed logging in peer ...: no peer auth method provided, please use a setup key or interactive SSO login ``` I also tried this on different devices with the same issue. Mobile devices like iOS get stuck on connecting. **Additional context** My docker compose file: ```yaml services: # Caddy reverse proxy caddy: image: caddy restart: unless-stopped networks: [ netbird ] ports: - '443:443' - '443:443/udp' - '80:80' volumes: - netbird_caddy_data:/data - ./Caddyfile:/etc/caddy/Caddyfile logging: driver: "json-file" options: max-size: "500m" max-file: "2" # UI dashboard dashboard: image: netbirdio/dashboard:latest restart: unless-stopped networks: [ netbird ] env_file: - ./dashboard.env logging: driver: "json-file" options: max-size: "500m" max-file: "2" # Signal signal: image: netbirdio/signal:latest restart: unless-stopped networks: [ netbird ] logging: driver: "json-file" options: max-size: "500m" max-file: "2" # Relay relay: image: netbirdio/relay:latest restart: unless-stopped networks: [netbird ] env_file: - ./relay.env logging: driver: "json-file" options: max-size: "500m" max-file: "2" # Management management: image: netbirdio/management:latest restart: unless-stopped networks: [ netbird ] depends_on: - dashboard volumes: - netbird_management:/var/lib/netbird - ./management.json:/etc/netbird/management.json command: [ "--port", "80", "--log-file", "console", "--log-level", "debug", "--disable-anonymous-metrics=false", "--single-account-mode-domain=net.REDACTED", "--dns-domain=net.REDACTED", "--idp-sign-key-refresh-enabled", ] logging: driver: "json-file" options: max-size: "500m" max-file: "2" # Coturn coturn: image: coturn/coturn:latest restart: unless-stopped domainname: REDACTED volumes: - ./turnserver.conf:/etc/turnserver.conf:ro network_mode: host command: - -c /etc/turnserver.conf logging: driver: "json-file" options: max-size: "500m" max-file: "2" volumes: netbird_management: netbird_caddy_data: networks: netbird: ``` The dashboard env: ```dotenv # Endpoints NETBIRD_MGMT_API_ENDPOINT=https://REDACTED:443 NETBIRD_MGMT_GRPC_API_ENDPOINT=https://REDACTED:443 # OIDC AUTH_AUDIENCE=REDACTED-AppID AUTH_CLIENT_ID=REDACTED-AppID AUTH_AUTHORITY=https://login.microsoftonline.com/REDACTED-TenantID/v2.0 USE_AUTH0=false AUTH_SUPPORTED_SCOPES=openid profile email offline_access User.Read api://REDACTED-AppID/api AUTH_REDIRECT_URI=/auth AUTH_SILENT_REDIRECT_URI=/silent-auth NETBIRD_TOKEN_SOURCE=idToken # SSL NGINX_SSL_PORT=443 # Letsencrypt LETSENCRYPT_DOMAIN=none ``` Caddyfile ``` { debug servers :80,:443 { protocols h1 h2c } } (security_headers) { header * { # enable HSTS # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#strict-transport-security-hsts # NOTE: Read carefully how this header works before using it. # If the HSTS header is misconfigured or if there is a problem with # the SSL/TLS certificate being used, legitimate users might be unable # to access the website. For example, if the HSTS header is set to a # very long duration and the SSL/TLS certificate expires or is revoked, # legitimate users might be unable to access the website until # the HSTS header duration has expired. # The recommended value for the max-age is 2 year (63072000 seconds). # But we are using 1 hour (3600 seconds) for testing purposes # and ensure that the website is working properly before setting # to two years. Strict-Transport-Security "max-age=3600; includeSubDomains; preload" # disable clients from sniffing the media type # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-content-type-options X-Content-Type-Options "nosniff" # clickjacking protection # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-frame-options X-Frame-Options "SAMEORIGIN" # xss protection # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#x-xss-protection X-XSS-Protection "1; mode=block" # Remove -Server header, which is an information leak # Remove Caddy from Headers -Server # keep referrer data off of HTTP connections # https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html#referrer-policy Referrer-Policy strict-origin-when-cross-origin } } :80, REDACTED:443 { import security_headers # relay reverse_proxy /relay* relay:80 # Signal reverse_proxy /signalexchange.SignalExchange/* h2c://signal:10000 # Management reverse_proxy /api/* management:80 reverse_proxy /management.ManagementService/* h2c://management:80 # Dashboard reverse_proxy /* dashboard:80 } ``` management.json ```json { "Stuns": [ { "Proto": "udp", "URI": "stun:REDACTED:3478", "Username": "", "Password": "" } ], "TURNConfig": { "TimeBasedCredentials": false, "CredentialsTTL": "12h0m0s", "Secret": "secret", "Turns": [ { "Proto": "udp", "URI": "turn:REDACTED:3478", "Username": "self", "Password": "REDACTED" } ] }, "Relay": { "Addresses": [ "rel://REDACTED:443" ], "CredentialsTTL": "24h0m0s", "Secret": "REDACTED" }, "Signal": { "Proto": "https", "URI": "REDACTED:443", "Username": "", "Password": "" }, "Datadir": "/var/lib/netbird/", "DataStoreEncryptionKey": "REDACTED", "HttpConfig": { "LetsEncryptDomain": "", "CertFile": "", "CertKey": "", "AuthAudience": "REDACTED-AppID", "AuthIssuer": "https://login.microsoftonline.com/REDACTED-TenantID/v2.0", "AuthUserIDClaim": "oid", "AuthKeysLocation": "https://login.microsoftonline.com/REDACTED-TenantID/discovery/v2.0/keys", "OIDCConfigEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/v2.0/.well-known/openid-configuration", "IdpSignKeyRefreshEnabled": false, "ExtraAuthAudience": "" }, "IdpManagerConfig": { "ManagerType": "azure", "ClientConfig": { "Issuer": "https://login.microsoftonline.com/REDACTED-TenantID/v2.0", "TokenEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/token", "ClientID": "REDACTED-AppID", "ClientSecret": "REDACTED-AppSecret", "GrantType": "client_credentials" }, "ExtraConfig": { "GraphApiEndpoint": "https://graph.microsoft.com/v1.0", "ObjectId": "REDACTED-ObjectID" }, "Auth0ClientCredentials": null, "AzureClientCredentials": null, "KeycloakClientCredentials": null, "ZitadelClientCredentials": null }, "DeviceAuthorizationFlow": { "Provider": "none", "ProviderConfig": { "ClientID": "", "ClientSecret": "", "Domain": "", "Audience": "REDACTED-AppID", "TokenEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/token", "DeviceAuthEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/devicecode", "AuthorizationEndpoint": "", "Scope": "openid", "UseIDToken": false, "RedirectURLs": null, "DisablePromptLogin": false } }, "PKCEAuthorizationFlow": { "ProviderConfig": { "ClientID": "REDACTED-AppID", "ClientSecret": "", "Domain": "", "Audience": "REDACTED-AppID", "TokenEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/token", "DeviceAuthEndpoint": "", "AuthorizationEndpoint": "https://login.microsoftonline.com/REDACTED-TenantID/oauth2/v2.0/authorize", "Scope": "openid profile email offline_access User.Read api://REDACTED-AppID/api", "UseIDToken": false, "RedirectURLs": [ "http://localhost:53000" ], "DisablePromptLogin": false } }, "StoreConfig": { "Engine": "sqlite" }, "ReverseProxy": { "TrustedHTTPProxies": [], "TrustedHTTPProxiesCount": 0, "TrustedPeers": [ "0.0.0.0/0" ] } } ``` **Have you tried these troubleshooting steps?** - [x] Checked for newer NetBird versions - [x] Searched for similar issues on GitHub (including closed ones) - [x] Restarted the NetBird client - [x] Disabled other VPN software - [x] Checked firewall settings
saavagebueno added the triage-needed label 2026-08-05 01:15:25 -04:00
Sign in to join this conversation.
No Label triage-needed
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#7965