usememos/memos · critical

deployment configuration disables password authentication fo

Error message

deployment configuration disables password authentication for regular users but has no effective identity provider

What it means

A cross-file safety check (validateDeploymentAuthenticationState): the deployment configuration disables password authentication for regular users (via the GENERAL setting's disallowPasswordAuth-like option) but there is no effective identity provider — neither in the deployment files nor stored in the database. Accepting this config would lock every regular user out of sign-in, so LoadDeploymentConfiguration returns this error and the configuration is not published.

Source

Thrown at store/deployment_config.go:385

	if configured := config.instanceSettings[storepb.InstanceSettingKey_GENERAL]; configured != nil {
		general = cloneInstanceSetting(configured)
	}
	if general == nil || !general.GetGeneralSetting().DisallowPasswordAuth {
		return nil
	}
	providers, err := s.listStoredIdentityProviders(ctx, &FindIdentityProvider{})
	if err != nil {
		return errors.Wrap(err, "failed to read stored identity providers")
	}
	effectiveUIDs := map[string]struct{}{}
	for _, provider := range providers {
		effectiveUIDs[provider.Uid] = struct{}{}
	}
	for uid := range config.identityProviders {
		effectiveUIDs[uid] = struct{}{}
	}
	if len(effectiveUIDs) == 0 {
		return errors.New("deployment configuration disables password authentication for regular users but has no effective identity provider")
	}
	return nil
}

func (s *Store) warnShadowedStoredIdentityProviders(ctx context.Context, config *deploymentConfiguration) error {
	if len(config.identityProviders) == 0 {
		return nil
	}
	providers, err := s.listStoredIdentityProviders(ctx, &FindIdentityProvider{})
	if err != nil {
		return errors.Wrap(err, "failed to inspect stored identity providers")
	}
	for _, provider := range providers {
		if _, ok := config.identityProviders[provider.Uid]; ok {
			slog.Warn("deployment identity provider shadows a stored provider; the stored configuration remains in the database", "uid", provider.Uid)
		}
	}
	return nil

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Ship a valid memos-idp-*.json file (in /etc/secrets) alongside the GENERAL setting that disables password auth.
  2. Or keep password auth enabled until the IdP file is verified to load (check the 'loaded deployment configuration' log line counts identityProviders > 0).
  3. Or pre-create the IdP through the admin UI/API so it is stored in the database before disabling passwords.

Example fix

// before: only memos-instance-setting-general.json with password auth disabled, no idp file
// after: also mount /etc/secrets/memos-idp-github.json
{ "uid": "github", "name": "GitHub", "type": "OAUTH2",
  "config": { "oauth2Config": { "clientId": "...", "clientSecret": "...", "authUrl": "...", "tokenUrl": "...", "userInfoUrl": "...", "scopes": ["read:user"], "fieldMapping": { "identifier": "login" } } } }
Defensive patterns

Strategy: validation

Validate before calling

// Before disabling password auth in the GENERAL file, confirm an IdP exists
idpCount := 0 // count memos-idp-*.json files matching ^memos-idp-[a-z0-9-]+\.json$ in the config dir
if idpCount == 0 {
    return errors.New("refusing to disable password auth: no identity provider deployed or stored")
}

Prevention

When it happens

Trigger: The GENERAL instance-setting file disables password auth while no memos-idp-*.json file exists and no IdP was previously created through the admin API; or all IdP files were deleted in the same deployment that disables passwords.

Common situations: Hardening a deployment to SSO-only and forgetting to ship the IdP file; a typo'd IdP filename (not matching memos-idp-*.json) so the file is silently ignored while the GENERAL file still disables passwords.

Understand the failure class

Related errors


AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15). Data as JSON: /api/errors/e4cf50fc35662301. Report an issue: GitHub.