[GH-ISSUE #5791] After migration from legacy zitadel IdP to Dex, login via Zitadel reports "Errors.App.NotFound" #11083

Closed
opened 2026-08-05 01:28:25 -04:00 by saavagebueno · 11 comments
Owner

Originally created by @undes1red on GitHub (Apr 2, 2026).
Original GitHub issue: https://github.com/netbirdio/netbird/issues/5791

Describe the problem

I followed the migration tutorial here. The migration succeeded as https://<your-domain>/oauth2/.well-known/openid-configuration returns a valid json and my private networks are functioning. However, I can not log into the dashboard. The Continue with Email does not accept my credentials, and Continue with Zitadel shows Errors.App.NotFound. I affirm the AUTH_AUTHORITY is set to https://<your-domain>/oauth2 and I restarted the dashboard container, so I don't know why dashboard still redirects to oauth/v2.

To Reproduce

Steps to reproduce the behavior:

  1. Migrate a legacy Zitadel deployment to Dex following this tutorial.
  2. Open the dashboard.
  3. Click Continue with Zitadel
  4. See the error.

Expected behavior

I should see the zitadel login page and I can log in using my old credentials.

Are you using NetBird Cloud?

Self-hosted

NetBird version

0.67.2

Is any other VPN software installed?

No.

Debug output

docker-compose.yaml

services:
  # Caddy reverse proxy
  caddy:
    image: caddy
    restart: unless-stopped
    networks: [ netbird ]
    ports:
      - '<my_ip>:443'
      - '<my_ip>:443/udp'
      - '<my_ip>:80'
      - '<my_ip>:8080'
    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]
    ports:
      - '3478:3478/udp'  # STUN UDP port (add more lines if using multiple ports)
    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]
    volumes:
      - netbird_management:/var/lib/netbird
      - ./management.json:/etc/netbird/management.json
    command: [
      "--port", "80",
      "--log-file", "console",
      "--log-level", "info",
      "--disable-anonymous-metrics=false",
      "--single-account-mode-domain=netbird.selfhosted",
      "--dns-domain=netbird.selfhosted",
      "--idp-sign-key-refresh-enabled",
    ]
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # Zitadel - identity provider
  zitadel:
    restart: 'always'
    networks: [netbird]
    image: 'ghcr.io/zitadel/zitadel:v2.64.1'
    command: 'start-from-init --masterkeyFromEnv --tlsMode external'
    env_file:
      - ./zitadel.env
    depends_on:
      zdb:
        condition: 'service_healthy'
    volumes:
      - ./machinekey:/machinekey
      - netbird_zitadel_certs:/zdb-certs:ro
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

  # Postgres for Zitadel
  zdb:
    restart: 'always'
    networks: [netbird]
    image: 'postgres:16-alpine'
    env_file:
      - ./zdb.env
    volumes:
      - netbird_zdb_data:/var/lib/postgresql/data:rw
    healthcheck:
      test: ["CMD-SHELL", "pg_isready", "-d", "db_prod"]
      interval: 5s
      timeout: 60s
      retries: 10
      start_period: 5s
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "2"

volumes:
  netbird_zdb_data:
    external: true
  netbird_management:
    external: true
  netbird_caddy_data:
    external: true
  netbird_zitadel_certs:
    external: true

networks:
  netbird:

dashboard.env:

# Endpoints
NETBIRD_MGMT_API_ENDPOINT=https://<my-domain>
NETBIRD_MGMT_GRPC_API_ENDPOINT=https://<my-domain>
# OIDC
USE_AUTH0=false
AUTH_AUDIENCE=netbird-dashboard
AUTH_CLIENT_ID=netbird-dashboard
AUTH_AUTHORITY=https://<my-domain>/oauth2
AUTH_SUPPORTED_SCOPES=openid profile email groups
AUTH_REDIRECT_URI=/nb-auth
AUTH_SILENT_REDIRECT_URI=/nb-silent-auth
# SSL
NGINX_SSL_PORT=443
# Letsencrypt
LETSENCRYPT_DOMAIN=none

Caddyfile:

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

(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, tunnel.qkv.link:443 {
    # handle /.well-known/microsoft-identity-association.json {
    #     root * /hostfile
    #     file_server
    # }
    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
    reverse_proxy /oauth2/* management:80
    # Zitadel
    reverse_proxy /zitadel.admin.v1.AdminService/* h2c://zitadel:8080
    reverse_proxy /admin/v1/* h2c://zitadel:8080
    reverse_proxy /zitadel.auth.v1.AuthService/* h2c://zitadel:8080
    reverse_proxy /auth/v1/* h2c://zitadel:8080
    reverse_proxy /zitadel.management.v1.ManagementService/* h2c://zitadel:8080
    reverse_proxy /management/v1/* h2c://zitadel:8080
    reverse_proxy /zitadel.system.v1.SystemService/* h2c://zitadel:8080
    reverse_proxy /system/v1/* h2c://zitadel:8080
    reverse_proxy /assets/v1/* h2c://zitadel:8080
    reverse_proxy /ui/* h2c://zitadel:8080
    reverse_proxy /oidc/v1/* h2c://zitadel:8080
    reverse_proxy /saml/v2/* h2c://zitadel:8080
    reverse_proxy /oauth/v2/* h2c://zitadel:8080
    reverse_proxy /.well-known/openid-configuration h2c://zitadel:8080
    reverse_proxy /openapi/* h2c://zitadel:8080
    reverse_proxy /debug/* h2c://zitadel:8080
    reverse_proxy /device/* h2c://zitadel:8080
    reverse_proxy /device h2c://zitadel:8080
    # Dashboard
    reverse_proxy /* dashboard:80
}

Screenshots

Image

Have you tried these troubleshooting steps?

  • Reviewed client troubleshooting (if applicable)
  • 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 @undes1red on GitHub (Apr 2, 2026). Original GitHub issue: https://github.com/netbirdio/netbird/issues/5791 **Describe the problem** I followed the migration tutorial [here](https://docs.netbird.io/selfhosted/migration/external-to-embedded-idp). The migration succeeded as `https://<your-domain>/oauth2/.well-known/openid-configuration` returns a valid json and my private networks are functioning. However, I can not log into the dashboard. The `Continue with Email` does not accept my credentials, and `Continue with Zitadel` shows `Errors.App.NotFound`. I affirm the `AUTH_AUTHORITY` is set to `https://<your-domain>/oauth2` and I restarted the dashboard container, so I don't know why dashboard still redirects to `oauth/v2`. **To Reproduce** Steps to reproduce the behavior: 1. Migrate a legacy Zitadel deployment to Dex following this [tutorial]((https://docs.netbird.io/selfhosted/migration/external-to-embedded-idp)). 2. Open the dashboard. 3. Click `Continue with Zitadel` 4. See the error. **Expected behavior** I should see the zitadel login page and I can log in using my old credentials. **Are you using NetBird Cloud?** Self-hosted **NetBird version** 0.67.2 **Is any other VPN software installed?** No. **Debug output** docker-compose.yaml ``` services: # Caddy reverse proxy caddy: image: caddy restart: unless-stopped networks: [ netbird ] ports: - '<my_ip>:443' - '<my_ip>:443/udp' - '<my_ip>:80' - '<my_ip>:8080' 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] ports: - '3478:3478/udp' # STUN UDP port (add more lines if using multiple ports) 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] volumes: - netbird_management:/var/lib/netbird - ./management.json:/etc/netbird/management.json command: [ "--port", "80", "--log-file", "console", "--log-level", "info", "--disable-anonymous-metrics=false", "--single-account-mode-domain=netbird.selfhosted", "--dns-domain=netbird.selfhosted", "--idp-sign-key-refresh-enabled", ] logging: driver: "json-file" options: max-size: "500m" max-file: "2" # Zitadel - identity provider zitadel: restart: 'always' networks: [netbird] image: 'ghcr.io/zitadel/zitadel:v2.64.1' command: 'start-from-init --masterkeyFromEnv --tlsMode external' env_file: - ./zitadel.env depends_on: zdb: condition: 'service_healthy' volumes: - ./machinekey:/machinekey - netbird_zitadel_certs:/zdb-certs:ro logging: driver: "json-file" options: max-size: "500m" max-file: "2" # Postgres for Zitadel zdb: restart: 'always' networks: [netbird] image: 'postgres:16-alpine' env_file: - ./zdb.env volumes: - netbird_zdb_data:/var/lib/postgresql/data:rw healthcheck: test: ["CMD-SHELL", "pg_isready", "-d", "db_prod"] interval: 5s timeout: 60s retries: 10 start_period: 5s logging: driver: "json-file" options: max-size: "500m" max-file: "2" volumes: netbird_zdb_data: external: true netbird_management: external: true netbird_caddy_data: external: true netbird_zitadel_certs: external: true networks: netbird: ``` dashboard.env: ``` # Endpoints NETBIRD_MGMT_API_ENDPOINT=https://<my-domain> NETBIRD_MGMT_GRPC_API_ENDPOINT=https://<my-domain> # OIDC USE_AUTH0=false AUTH_AUDIENCE=netbird-dashboard AUTH_CLIENT_ID=netbird-dashboard AUTH_AUTHORITY=https://<my-domain>/oauth2 AUTH_SUPPORTED_SCOPES=openid profile email groups AUTH_REDIRECT_URI=/nb-auth AUTH_SILENT_REDIRECT_URI=/nb-silent-auth # SSL NGINX_SSL_PORT=443 # Letsencrypt LETSENCRYPT_DOMAIN=none ``` Caddyfile: ``` { debug servers :80,:443 { protocols h1 h2c h2 h3 } } (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, tunnel.qkv.link:443 { # handle /.well-known/microsoft-identity-association.json { # root * /hostfile # file_server # } 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 reverse_proxy /oauth2/* management:80 # Zitadel reverse_proxy /zitadel.admin.v1.AdminService/* h2c://zitadel:8080 reverse_proxy /admin/v1/* h2c://zitadel:8080 reverse_proxy /zitadel.auth.v1.AuthService/* h2c://zitadel:8080 reverse_proxy /auth/v1/* h2c://zitadel:8080 reverse_proxy /zitadel.management.v1.ManagementService/* h2c://zitadel:8080 reverse_proxy /management/v1/* h2c://zitadel:8080 reverse_proxy /zitadel.system.v1.SystemService/* h2c://zitadel:8080 reverse_proxy /system/v1/* h2c://zitadel:8080 reverse_proxy /assets/v1/* h2c://zitadel:8080 reverse_proxy /ui/* h2c://zitadel:8080 reverse_proxy /oidc/v1/* h2c://zitadel:8080 reverse_proxy /saml/v2/* h2c://zitadel:8080 reverse_proxy /oauth/v2/* h2c://zitadel:8080 reverse_proxy /.well-known/openid-configuration h2c://zitadel:8080 reverse_proxy /openapi/* h2c://zitadel:8080 reverse_proxy /debug/* h2c://zitadel:8080 reverse_proxy /device/* h2c://zitadel:8080 reverse_proxy /device h2c://zitadel:8080 # Dashboard reverse_proxy /* dashboard:80 } ``` **Screenshots** <img width="3368" height="563" alt="Image" src="https://github.com/user-attachments/assets/d307b256-56b2-4515-994e-dbf5886cada0" /> **Have you tried these troubleshooting steps?** - [x] Reviewed [client troubleshooting](https://docs.netbird.io/how-to/troubleshooting-client) (if applicable) - [ ] Checked for newer NetBird versions - [ ] Searched for similar issues on GitHub (including closed ones) - [x] Restarted the NetBird client - [ ] Disabled other VPN software - [ ] Checked firewall settings
saavagebueno added the triage-needed label 2026-08-05 01:28:25 -04:00
Author
Owner

@pernetz commented on GitHub (Apr 3, 2026):

That's a good one! I am under preparation to also migrate my setup from legacy IdP to Dex. I will stop my efforts for now until this has been figured out.

What comes into my mind:
Are you sure your Zitadel instance is reachable via the web? Since the migration script requires the static connector config, what did you set there?
I was not sure which issuer domain to insert here: "config": { "issuer": "https://idp.example.com", ... }

In the legacy setup Zitadel had no dedicated domain name. It utilizes the forwarder https://<your-domain>/ui/console proxied by caddyfile entry reverse_proxy /ui/* h2c://zitadel:8080, I believe.

According to my understanding the connector config must be https://<your-domain> - that's it.

Maybe we can find out together. Keep me posted.

<!-- gh-comment-id:4183122366 --> @pernetz commented on GitHub (Apr 3, 2026): That's a good one! I am under preparation to also migrate my setup from legacy IdP to Dex. I will stop my efforts for now until this has been figured out. What comes into my mind: Are you sure your Zitadel instance is reachable via the web? Since the migration script requires the static connector config, what did you set there? I was not sure which issuer domain to insert here: `"config": { "issuer": "https://idp.example.com", ... }` In the legacy setup Zitadel had no dedicated domain name. It utilizes the forwarder `https://<your-domain>/ui/console` proxied by caddyfile entry `reverse_proxy /ui/* h2c://zitadel:8080`, I believe. According to my understanding the connector config must be `https://<your-domain>` - that's it. Maybe we can find out together. Keep me posted.
Author
Owner

@undes1red commented on GitHub (Apr 3, 2026):

Hello @pernetz. I can access the zitadel instance at https://<your-domain>/ui/console. The issuer domain I believe is HttpConfig.AuthIssuer in your management.json.

<!-- gh-comment-id:4183152385 --> @undes1red commented on GitHub (Apr 3, 2026): Hello @pernetz. I can access the zitadel instance at `https://<your-domain>/ui/console`. The issuer domain I believe is `HttpConfig.AuthIssuer` in your `management.json`.
Author
Owner

@pernetz commented on GitHub (Apr 3, 2026):

Hi @undes1red Awesome, that is definetifely the easier way to find out. However, it confirms my guess above https://<your-domain> is correct.

Check your Caddyfile, under # Zitadel it still proxies to reverse_proxy /oauth/v2/* h2c://zitadel:8080

<!-- gh-comment-id:4183282511 --> @pernetz commented on GitHub (Apr 3, 2026): Hi @undes1red Awesome, that is definetifely the easier way to find out. However, it confirms my guess above `https://<your-domain>` is correct. Check your Caddyfile, under `# Zitadel` it still proxies to `reverse_proxy /oauth/v2/* h2c://zitadel:8080`
Author
Owner

@undes1red commented on GitHub (Apr 3, 2026):

reverse_proxy /oauth/v2/* h2c://zitadel:8080 comes with the default caddy config and the migration tutorial does not ask to change it. I also tried to remove it yesterday. Removing it caused clicking Continue with Zitadel jumped back to the netbird sign in page.

<!-- gh-comment-id:4183305044 --> @undes1red commented on GitHub (Apr 3, 2026): `reverse_proxy /oauth/v2/* h2c://zitadel:8080` comes with the default caddy config and the migration tutorial does not ask to change it. I also tried to remove it yesterday. Removing it caused clicking `Continue with Zitadel` jumped back to the netbird sign in page.
Author
Owner

@pernetz commented on GitHub (Apr 3, 2026):

Allright got your point. I guess the migration guide is well tested. I just read through the steps beyond the dry-run execution. I must admit your configuration files apperantly look ok.

Did you try to docker compose up -d --force-recreate the management container?

<!-- gh-comment-id:4183693350 --> @pernetz commented on GitHub (Apr 3, 2026): Allright got your point. I guess the migration guide is well tested. I just read through the steps beyond the dry-run execution. I must admit your configuration files apperantly look ok. Did you try to `docker compose up -d --force-recreate` the management container?
Author
Owner

@pernetz commented on GitHub (Apr 3, 2026):

Hey @undes1red Your dashboard.env is wrong. You are missing the USE_AUTH0=false line from previous configuration.
Insert and perform docker compose up dashboard (without -d) to check the log for errors during container startup.

Hope this works for you.

<!-- gh-comment-id:4184069783 --> @pernetz commented on GitHub (Apr 3, 2026): Hey @undes1red Your `dashboard.env` is wrong. You are missing the `USE_AUTH0=false` line from previous configuration. Insert and perform `docker compose up dashboard` (without `-d`) to check the log for errors during container startup. Hope this works for you.
Author
Owner

@undes1red commented on GitHub (Apr 3, 2026):

@pernetz I tried docker compose up -d --force-recreate but has no effect. Also USE_AUTH0=false is in my dashboard.env. It is right below the # OIDC line.

<!-- gh-comment-id:4185936011 --> @undes1red commented on GitHub (Apr 3, 2026): @pernetz I tried `docker compose up -d --force-recreate` but has no effect. Also `USE_AUTH0=false` is in my `dashboard.env`. It is right below the `# OIDC` line.
Author
Owner

@pernetz commented on GitHub (Apr 4, 2026):

@undes1red Aweee true that, I am sorry. Actually I am running out of ideas.

Have you checked the log for any errors while recreation? docker compose logs -f management
Else, are you sure the Zitadel credentials (ClientID and ClientSecret) are correct on both sides, zitadel web app and connector.json?

I finished the migration successful yesterday. The only issue I ran into was the missing USE_AUTH.

<!-- gh-comment-id:4186630528 --> @pernetz commented on GitHub (Apr 4, 2026): @undes1red Aweee true that, I am sorry. Actually I am running out of ideas. Have you checked the log for any errors while recreation? `docker compose logs -f management` Else, are you sure the Zitadel credentials (ClientID and ClientSecret) are correct on both sides, `zitadel web app` and `connector.json`? I finished the migration successful yesterday. The only issue I ran into was the missing `USE_AUTH`.
Author
Owner

@undes1red commented on GitHub (Apr 4, 2026):

No worries. I checked the log of management and the only error is management-1 | 2026-04-04T01:24:33.400Z ERRO [id: accounts, err: failed to open connector: failed to create connector accounts: failed to get provider: 502 Bad Gateway: ] idp/dex/logrus_handler.go:83: server: Failed to open connector though I have no idea what this means.
I reread the tutorial and I think I might use the wrong client id and secret. Where do you get your client ID and secret? I got mine at IdpManagerConfig.ClientConfig.ClientID and IdpManagerConfig.ClientConfig.ClientSecret in the old management.json.

<!-- gh-comment-id:4186772077 --> @undes1red commented on GitHub (Apr 4, 2026): No worries. I checked the log of `management` and the only error is `management-1 | 2026-04-04T01:24:33.400Z ERRO [id: accounts, err: failed to open connector: failed to create connector accounts: failed to get provider: 502 Bad Gateway: ] idp/dex/logrus_handler.go:83: server: Failed to open connector` though I have no idea what this means. I reread the tutorial and I think I might use the wrong client id and secret. Where do you get your client ID and secret? I got mine at `IdpManagerConfig.ClientConfig.ClientID` and `IdpManagerConfig.ClientConfig.ClientSecret` in the old `management.json`.
Author
Owner

@pernetz commented on GitHub (Apr 4, 2026):

This error message looks familiar to me. Mine pointed also to an issure with the connector, as far as I remember.

Your proceeding was wrong. You must register a new project and app inside your Zitadel console according to this guide: https://docs.netbird.io/selfhosted/identity-providers/zitadel
Therein you will get new keys for both, ClientID and ClientSecret. These keys are to be filled in the connector.json.

Good luck!

<!-- gh-comment-id:4186814210 --> @pernetz commented on GitHub (Apr 4, 2026): This error message looks familiar to me. Mine pointed also to an issure with the connector, as far as I remember. Your proceeding was wrong. You must register a new project and app inside your Zitadel console according to this guide: [https://docs.netbird.io/selfhosted/identity-providers/zitadel](url) Therein you will get new keys for both, `ClientID` and `ClientSecret`. These keys are to be filled in the `connector.json`. Good luck!
Author
Owner

@undes1red commented on GitHub (Apr 4, 2026):

Hooary! The migration worked. Thank you @pernetz.

<!-- gh-comment-id:4186886599 --> @undes1red commented on GitHub (Apr 4, 2026): Hooary! The migration worked. Thank you @pernetz.
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#11083