netbirdio/netbird · error

identity provider issuer is unreachable

Error message

identity provider issuer is unreachable

What it means

Sentinel error types.ErrIdentityProviderIssuerUnreachable (management/server/types/identity_provider.go:15), wrapped by validateOIDCIssuer (management/server/identity_provider.go:33-70): when saving an IdP config, management performs a live GET of {issuer}/.well-known/openid-configuration with a 10s timeout. This error means that probe failed to connect, returned a non-200 status, or the body was not a discovery document.

Source

Thrown at management/server/types/identity_provider.go:15

package types

import (
	"errors"
	"net/url"
)

// Identity provider validation errors
var (
	ErrIdentityProviderNameRequired      = errors.New("identity provider name is required")
	ErrIdentityProviderTypeRequired      = errors.New("identity provider type is required")
	ErrIdentityProviderTypeUnsupported   = errors.New("unsupported identity provider type")
	ErrIdentityProviderIssuerRequired    = errors.New("identity provider issuer is required")
	ErrIdentityProviderIssuerInvalid     = errors.New("identity provider issuer must be a valid URL")
	ErrIdentityProviderIssuerUnreachable = errors.New("identity provider issuer is unreachable")
	ErrIdentityProviderIssuerMismatch    = errors.New("identity provider issuer does not match the issuer returned by the provider")
	ErrIdentityProviderClientIDRequired  = errors.New("identity provider client ID is required")
)

// IdentityProviderType is the type of identity provider
type IdentityProviderType string

const (
	// IdentityProviderTypeOIDC is a generic OIDC identity provider
	IdentityProviderTypeOIDC IdentityProviderType = "oidc"
	// IdentityProviderTypeZitadel is the Zitadel identity provider
	IdentityProviderTypeZitadel IdentityProviderType = "zitadel"
	// IdentityProviderTypeEntra is the Microsoft Entra (Azure AD) identity provider
	IdentityProviderTypeEntra IdentityProviderType = "entra"
	// IdentityProviderTypeGoogle is the Google identity provider
	IdentityProviderTypeGoogle IdentityProviderType = "google"
	// IdentityProviderTypeOkta is the Okta identity provider
	IdentityProviderTypeOkta IdentityProviderType = "okta"

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. From inside the management container/host, curl the exact URL in the error: {issuer}/.well-known/openid-configuration and confirm HTTP 200
  2. Fix the network path: DNS resolution, egress proxy env vars, firewall rules, or use an issuer host reachable from management
  3. If TLS is the cause, make sure the IdP certificate chain is valid for the management host (CA bundle of the container)
  4. If the IdP was transiently down, retry the save once it is healthy

Example fix

// before: issuer only resolvable from user laptops, not from management
idp.Issuer = "https://sso.corp.internal/realms/nb" // management container cannot resolve corp.internal

// after: issuer reachable from the management network
idp.Issuer = "https://sso.internal.svc.cluster.local/realms/nb"
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight from the same host/container that runs management
func issuerReachable(ctx context.Context, issuer string) error {
    c := &http.Client{Timeout: 10 * time.Second}
    req, _ := http.NewRequestWithContext(ctx, http.MethodGet,
        strings.TrimSuffix(issuer, "/")+"/.well-known/openid-configuration", nil)
    resp, err := c.Do(req)
    if err != nil { return err }
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK { return fmt.Errorf("discovery returned %s", resp.Status) }
    return nil
}

Try / catch

err := saveIdP(ctx, idp)
if err != nil && errors.Is(err, types.ErrIdentityProviderIssuerUnreachable) {
    // read the wrapped cause; only retry for transient causes (timeouts, 503),
    // fix DNS/firewall/TLS for permanent ones
}

Prevention

When it happens

Trigger: Saving an IdP whose issuer host cannot be reached from the management server process: DNS failure, firewall/proxy block, TLS handshake failure, 404/500 from the well-known path, or a >10s slow response. The exact cause is appended (%w wrap with status/body/err detail).

Common situations: Management running in Docker/Kubernetes without access to the internal IdP host; IdP behind a self-signed certificate not trusted by the management container; issuer pointing to the public URL while the IdP is only reachable internally; IdP briefly down during IaC apply.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/a1dc3a565d9251d6. Report an issue: GitHub.