{"record":{"id":"521075ac1bc25ffe","repo":"netbirdio/netbird","slug":"identity-provider-issuer-must-be-a-valid-url","errorCode":null,"errorMessage":"identity provider issuer must be a valid URL","messagePattern":"identity provider issuer must be a valid URL","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"management/server/types/identity_provider.go","lineNumber":14,"sourceCode":"package types\n\nimport (\n\t\"errors\"\n\t\"net/url\"\n)\n\n// Identity provider validation errors\nvar (\n\tErrIdentityProviderNameRequired      = errors.New(\"identity provider name is required\")\n\tErrIdentityProviderTypeRequired      = errors.New(\"identity provider type is required\")\n\tErrIdentityProviderTypeUnsupported   = errors.New(\"unsupported identity provider type\")\n\tErrIdentityProviderIssuerRequired    = errors.New(\"identity provider issuer is required\")\n\tErrIdentityProviderIssuerInvalid     = errors.New(\"identity provider issuer must be a valid URL\")\n\tErrIdentityProviderIssuerUnreachable = errors.New(\"identity provider issuer is unreachable\")\n\tErrIdentityProviderIssuerMismatch    = errors.New(\"identity provider issuer does not match the issuer returned by the provider\")\n\tErrIdentityProviderClientIDRequired  = errors.New(\"identity provider client ID is required\")\n)\n\n// IdentityProviderType is the type of identity provider\ntype IdentityProviderType string\n\nconst (\n\t// IdentityProviderTypeOIDC is a generic OIDC identity provider\n\tIdentityProviderTypeOIDC IdentityProviderType = \"oidc\"\n\t// IdentityProviderTypeZitadel is the Zitadel identity provider\n\tIdentityProviderTypeZitadel IdentityProviderType = \"zitadel\"\n\t// IdentityProviderTypeEntra is the Microsoft Entra (Azure AD) identity provider\n\tIdentityProviderTypeEntra IdentityProviderType = \"entra\"\n\t// IdentityProviderTypeGoogle is the Google identity provider\n\tIdentityProviderTypeGoogle IdentityProviderType = \"google\"\n\t// IdentityProviderTypeOkta is the Okta identity provider","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/management/server/types/identity_provider.go#L1-L32","documentation":"Sentinel error types.ErrIdentityProviderIssuerInvalid (management/server/types/identity_provider.go:14), returned by IdentityProvider.Validate whenever Issuer is non-empty but url.Parse fails or the parsed URL has no scheme or host. The check accepts any parseable absolute URL, so failure almost always means a missing scheme (https://) or a malformed host.","triggerScenarios":"Saving an IdP with issuer like \"auth.example.com/realms/nb\" (no scheme), \"https:///path\" (no host), or a string containing control characters that url.Parse rejects.","commonSituations":"Operators pasting the issuer without https://; Terraform variables that strip the scheme; trailing whitespace or copy artifacts from web consoles; issuer taken from a metadata endpoint that returns a path-only value.","solutions":["Send a full absolute URL including scheme and host, e.g. https://auth.example.com/realms/netbird","Trim whitespace and verify the value with url.Parse client-side before submitting"],"exampleFix":"// before\nidp.Issuer = \"auth.example.com/realms/netbird\"\n\n// after\nidp.Issuer = \"https://auth.example.com/realms/netbird\"","handlingStrategy":"validation","validationCode":"func isValidIssuerURL(issuer string) bool {\n    if issuer == \"\" { return true } // emptiness is checked separately\n    u, err := url.Parse(strings.TrimSpace(issuer))\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}\n\nif !isValidIssuerURL(idp.Issuer) {\n    return types.ErrIdentityProviderIssuerInvalid\n}","typeGuard":null,"tryCatchPattern":"if err := idp.Validate(); err != nil {\n    if errors.Is(err, types.ErrIdentityProviderIssuerInvalid) {\n        // normalize: trim spaces, prepend https:// if missing, re-validate\n    }\n    return err\n}","preventionTips":["Run url.Parse + scheme/host checks client-side with the exact same rules as the server","Copy issuer URLs from the IdP's OIDC discovery settings, not from browser address bars with extra paths","Trim whitespace in config loaders before submitting"],"tags":["management","identity-provider","oidc","url","validation"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}